sched_setscheduler(2) e gli amici consentono di utilizzare due diversi programmatori soft in tempo reale, SCHED_FIFO SCHED_RR. I processi in esecuzione con questi programmi di pianificazione hanno una priorità maggiore rispetto ai processi normali. Quindi, fintanto che hai solo alcuni di questi processi e controlli le priorità tra di loro, puoi effettivamente ottenere risposte in tempo reale piuttosto discendenti.
Come richiesto in un commento, ecco la differenza tra SCHED_FIFO e SCHED_RR:
Con gli scheduler "in tempo reale", ci sono fino a 100 priorità diverse (POSIX richiede solo 32 livelli distinti, quindi si dovrebbe usare sched_get_priority_min(2) e sched_get_priority_max(2) per ottenere il numero effettivo. Entrambi gli scheduler funzionano anticipando i processi e thread con priorità inferiore, la differenza sta nel modo in cui gestiscono le attività con la stessa priorità.
SCHED_FIFO, è uno scheduler first in first out (da cui il nome). Ciò significa che l'attività che raggiunge per prima la coda di esecuzione può essere eseguita fino a quando non viene completata, rinuncia volontariamente al proprio spazio nella coda di esecuzione o viene preceduta da un'attività con priorità più alta.
SCHED_RR, è uno scheduler round robin. Ciò significa che le attività con la stessa priorità possono essere eseguite solo per un determinato quanto di tempo. Se l'attività è ancora in esecuzione quando questo intervallo di tempo si esaurisce, l'attività viene anticipata e l'attività successiva nella coda di esecuzione (con la stessa priorità) può essere eseguita fino al suo intervallo di tempo. Come con SCHED_FIFO, le attività con priorità più alta prevalgono su quelle con priorità più bassa, tuttavia, quando un'attività che è stata anticipata da un'attività con priorità più alta può essere eseguita di nuovo, allora può essere eseguita solo per il tempo rimasto nel suo quanto. Vedi la sezione Noes in sched_rr_get_interval(2) per come impostare il quanto di tempo per un'attività.
MRG
Sarà difficile garantire meno di un millisecondo su un kernel non RT. So che negli ultimi anni è stato svolto un ottimo lavoro (ad esempio, il blocco del kernel è stato eliminato), ma non è ancora sufficiente per garantirlo.
Potresti dare un'occhiata a Scientific Linux da quegli amichevoli disturbatori di atomi del CERN e del Fermilab. Questo può avere MRG installato (vedi il mio link), che ti dà una configurazione pre-pack della patch PREEMPT_RT.
O se hai i soldi potresti ottenere Redhat MRG. Questa è una distribuzione Linux completamente supportata con la patch PREEMPT-RT incorporata, in modo da eliminare il problema dell'applicazione di patch del kernel soggetta a problemi.
Il fatto è che RedHat fa pagare molto per questo ($ 3000 ALL'ANNO PER INSTALLAZIONE). Penso che abbiano capito che uno dei maggiori clienti sono gli investitori di trading ad alta velocità che hanno ancora un sacco di $ e quindi non si accorgeranno che $ 3000/scatola/anno escono dalla porta.
Come sono andato d'accordo con MRG
Ho fatto un bel po' di lavoro con MRG (usando entrambi i precedenti), ed è abbastanza buono. Sostituisce le routine di servizio di interrupt nel kernel di serie con thread per servire l'interrupt. Ciò significa che puoi eseguire il tuo software con priorità superiori ai thread IRQ! Questo è il genere di cose che devi fare se vuoi avvicinarti a garantire latenza inferiore al millisecondo sulla tua applicazione.
Sembra esserci una graduale deriva delle cose MRG nel kernel principale, il che è una buona cosa secondo me. Forse un giorno diventerà la cosa principale.
Altri trucchi
La moderna gestione termica della CPU può essere una vera spina nel fianco. Ho avuto sistemi che si bloccavano per 0,3 secondi mentre veniva riparato un interrupt di gestione del sistema (dal BIOS, non dal sistema operativo), solo perché la CPU si è riscaldata un po '. Guarda questo. Quindi devi stare attento a ciò che fa il tuo hardware sottostante. In genere devi iniziare a preoccuparti di abbandonare il raffreddamento gestito dei PC moderni e tornare a una grande ventola che gira sempre velocemente.
Puoi andare molto lontano con Linux rimuovendo il "disturbo" da altri processi al processo in tempo reale. Ho giocato con la stessa cosa in Windows, che è un orrore molto più grande da ottenere, ma mostra la direzione. Quindi una sorta di lista di controllo:
- La cosa più importante (strano ma vero):l'hardware. Non scegliere un laptop, questo sarà ottimizzato per fare cose strane durante le interruzioni SMM. Niente che tu possa fare.
- I driver:Linux (e Windows) ha driver cattivi e driver buoni. Relativo all'hardware. E c'è solo un modo per scoprirlo:il benchmarking.
Isola dal resto del sistema, disabilita tutte le condivisioni:
- Isola una CPU (
man cpuset
). Crea due set di CPU, uno per i processi normali e uno per il tuo processo in tempo reale. - Riduci al minimo la parte in tempo reale del tuo codice. Comunicare con buffer di grandi dimensioni con altre parti del sistema. Riduci IO al minimo indispensabile (poiché IO ha cattive garanzie).
- Fai in modo che il processo abbia la massima priorità in tempo reale (soft).
- Disabilita HyperThreading (non vuoi condividere)
- pre-allocare la memoria di cui hai bisogno e mlock() la memoria.
- Isola i dispositivi che utilizzi. Inizia assegnando un IRQ dedicato al dispositivo (sposta gli altri dispositivi su un altro IRQ o rimuovi altri dispositivi/driver).
- Isola l'IO che usi.
Riduci l'attività del resto del sistema:
- avvia solo i processi di cui hai veramente bisogno.
- rimuovi l'hardware che non ti serve come dischi e altro hardware.
- disattiva lo scambio.
- non usare i moduli del kernel Linux o caricarli in anticipo. L'init dei moduli è imprevedibile.
- preferibilmente rimuovi anche l'utente :)
Rendilo stabile e riproducibile:
- disattiva tutti i risparmi energetici. Vuoi sempre le stesse prestazioni.
- esamina tutte le impostazioni del BIOS e rimuovi tutti gli "eventi" e le "condivisioni" da esse. Quindi niente speedstep fantasiosi, gestione termica ecc. Scegli una bassa latenza, non scegliere cose con "burst" nel nome poiché in genere scambia il throughput con prestazioni peggiori.
- rivedi le impostazioni del driver Linux e le latenze inferiori (se applicabile).
- usa un kernel recente che ogni giorno cerca di assomigliare un po' di più a un kernel in tempo reale.
E poi benchmark, usando stress test e lasciando la macchina accesa per giorni durante la registrazione max. latenze.
Quindi:buona fortuna :)