Come posso garantire che il mio programma venga eseguito dall'inizio alla fine senza interruzioni?

StackOverflow https://stackoverflow.com/questions/1215713

  •  06-07-2019
  •  | 
  •  

Domanda

Sto tentando di timecode usando RDTSC (nessun altro software di profiling che ho provato è in grado di passare alla risoluzione di cui ho bisogno) su Ubuntu 8.10. Tuttavia, continuo a ottenere valori anomali dagli switch di attività e interrompe l'attivazione, il che rende le mie statistiche non valide.

Considerando che il mio programma viene eseguito in pochi millisecondi, è possibile disabilitare tutti gli interrupt (che disattiverebbero intrinsecamente gli switch di attività) nel mio ambiente? O devo andare a un sistema operativo che mi consente più potenza? Sarebbe meglio usare il mio kernel OS per eseguire questo codice di temporizzazione? Sto tentando di dimostrare le prestazioni migliori / peggiori di un algoritmo, quindi deve essere totalmente solido con i tempi.

Il codice pertinente che sto utilizzando attualmente è:

inline uint64_t rdtsc()
{
    uint64_t ret;
    asm volatile("rdtsc" : "=A" (ret));
    return ret;
}

void test(int readable_out, uint32_t start, uint32_t end, uint32_t (*fn)(uint32_t, uint32_t))
{
    int i;
    for(i = 0; i <= 100; i++)
    {
        uint64_t clock1 = rdtsc();
        uint32_t ans = fn(start, end);
        uint64_t clock2 = rdtsc();

        uint64_t diff = clock2 - clock1;

        if(readable_out)
            printf("[%3d]\t\t%u [%llu]\n", i, ans, diff);
        else
            printf("%llu\n", diff);
    }
}

Punti extra per coloro che notano che non sto gestendo correttamente le condizioni di overflow in questo codice. In questa fase sto solo cercando di ottenere un risultato coerente senza salti improvvisi a causa della perdita del timeslice del mio programma.

Il buon valore per il mio programma è -20.

Quindi, per ricapitolare, è possibile per me eseguire questo codice senza interruzione dal sistema operativo? O avrò bisogno di eseguirlo su hardware nudo in ring0, in modo da poter disabilitare IRQ e la pianificazione? Grazie in anticipo!

È stato utile?

Soluzione

Se chiami nanosleep () per dormire per un secondo circa immediatamente prima di ogni iterazione del test, dovresti ottenere un " fresco " timeslice per ogni test. Se compili il tuo kernel con interruzioni del timer da 100 HZ e la tua funzione cronometrata si completa in meno di 10 ms, allora dovresti essere in grado di evitare che le interruzioni del timer ti colpiscano in quel modo.

Per ridurre al minimo altri interrupt, deconfigura tutti i dispositivi di rete, configura il tuo sistema senza scambiare e assicurati che sia altrimenti sospeso.

Altri suggerimenti

Tricky. Non credo che tu possa disattivare il sistema operativo e garantire una pianificazione rigorosa.

Lo capovolgerei: dato che corre così veloce, eseguilo molte volte per raccogliere una distribuzione dei risultati. Dato che Ubuntu Linux standard non è un sistema operativo in tempo reale in senso stretto, tutti gli algoritmi alternativi funzionerebbero nella stessa configurazione --- e puoi quindi confrontare le tue distribuzioni (usando qualsiasi cosa, dalle statistiche di riepilogo ai quantili ai qqplot). Puoi fare quel confronto con Python, o R, o Octave, ... a seconda di quale ti si addice meglio.

Potresti riuscire a cavartela con FreeDOS , poiché è un singolo sistema operativo .

Ecco il testo pertinente dal secondo link:

  

L'implementazione DOS di Microsoft, che è il de   facto standard per i sistemi DOS nel   x86 world, è un utente singolo,   sistema operativo single-tasking. esso   fornisce un accesso non elaborato all'hardware e   solo un livello minimo per le API del sistema operativo per   cose come l'I / O dei file. Questo è un   buona cosa quando si tratta di incorporato   sistemi, perché spesso hai solo bisogno   per fare qualcosa senza un   sistema operativo a modo tuo.

     

DOS non ha (nativamente) alcun concetto di   discussioni e nessun concetto di multiplo,   processi in corso. Applicazione   il software effettua chiamate di sistema tramite   uso di un'interfaccia di interruzione, chiamata   vari interrupt di processo da gestire   cose come video e audio, e   chiamare gli interrupt software da gestire   varie cose come leggere a   directory, esecuzione di un file e così via   via.

Naturalmente, probabilmente otterrai le migliori prestazioni avviando FreeDOS sull'hardware reale, non in un emulatore.

In realtà non ho usato FreeDOS, ma suppongo che dal momento che il tuo programma sembra essere C standard, sarai in grado di usare qualunque sia il compilatore standard per FreeDOS.

Se il tuo programma viene eseguito in millisecondi e se sei in esecuzione su Linux, Assicurarsi che la frequenza del timer (su Linux) sia impostata su 100Hz (non 1000Hz). (cd / usr / src / linux; make menuconfig, e guarda " Tipo e caratteristiche del processore " - > " Frequenza del timer ") In questo modo la tua CPU verrà interrotta ogni 10 ms.

Inoltre, considera che l'intervallo di tempo predefinito della CPU su Linux è 100ms, quindi con un buon livello di -20, non verrai riprogrammato se stai funzionando per alcuni millisecondi.

Inoltre, stai eseguendo il loop 101 volte su fn (). Ti preghiamo di considerare di dare a fn () una no-op per calibrare correttamente il tuo sistema.

Crea statistiche (media + stddev) invece di stampare troppe volte (ciò consumerebbe il tuo timeslice programmato, e il terminale alla fine otterrà il programma ecc ... evitalo).

Codice campione benchmark RDTSC

Puoi usare chrt -f 99 ./test per eseguire ./test con la massima priorità in tempo reale. Quindi almeno non verrà interrotto da altri processi dello spazio utente.

Inoltre, l'installazione del pacchetto linux-rt installerà un kernel in tempo reale, che ti darà un maggiore controllo sulla priorità del gestore di interrupt tramite interruzioni thread.

Se corri come root, puoi chiamare sched_setscheduler () e darti una priorità in tempo reale. Controlla la documentazione.

Forse esiste un modo per disabilitare la pianificazione preventiva su Linux, ma potrebbe non essere necessario. Potresti potenzialmente utilizzare le informazioni di /proc/<pid>/schedstat o qualche altro oggetto in /proc per rilevare quando sei stato anticipato e ignorare quei campioni di temporizzazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top