2015-07-10 17 views
5

In C++ per Linux, sto provando a fare qualcosa ogni microsecondo/nanosecondo e sto attualmente utilizzando la funzione nanosleep qui sotto. Funziona, tuttavia se il codice viene ripetuto milioni di volte, questo diventa costoso. Sto cercando un timer ad alta risoluzione che consenta un timing molto preciso (l'applicazione è audio/video). Qualche idea?Cercare un timer ad alta risoluzione

struct timespec req = {0}; 
req.tv_sec = 0; 
req.tv_nsec = 1000000000L/value; 

for(long i = 0; i < done; i++) 
{ 
    printf("Hello world");    
    nanosleep(&req, (struct timespec *)NULL); 
} 
+2

Qualcosa non va con ''? – chris

+2

Se la tua CPU ha un clock a 4 GHz, hai 4 cicli di clock in un nanosecondo. Non puoi fare molto ogni nanosecondo, anche a quella velocità. –

+0

Di che tipo di linux e processore stiamo parlando? Per i sistemi non in tempo reale, qualsiasi valore superiore alla precisione ms è già abbastanza ambizioso. La precisione dei microsecondi (per non parlare dei nanosecondi) è qualcosa su cui non ci si aspetterebbe nemmeno la maggior parte dei sistemi in tempo reale. – MikeMB

risposta

4

Utilizzando C++11

#include <chrono> 
#include <thread> 

... 

for (long i = 0; i < done; i++) { 
    std::cout << "Hello world" << std::endl;    
    std::this_thread::sleep_for(std::chrono::nanoseconds(1e9/value)); 
} 

Ricordati di compilare con -std=c++11 bandiera.

+0

Ho confrontato i due approcci e sembrano avere una spesa computazionale molto simile (la chiamata di sistema richiede molto tempo). E 'davvero il meglio che si può fare, o è possibile usare un timer speciale direttamente dal kernel o qualcosa del genere? – Josh

+0

@Josh Penso che questo sia il meglio che si possa fare dal lato utente. – Shreevardhan

0

È possibile ottenere risoluzione microsecondo con getitimer (2):

http://man7.org/linux/man-pages/man2/setitimer.2.html

+0

Nota che POSIX contrassegna ['setitimer()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/setitimer.html) e ['getitimer()'] (http: //pubs.opengroup .org/onlinepubs/9699919799/functions/getitimer.html) come obsoleto, e afferma che le funzioni di sostituzione preferite sono ['timer_settime()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_settime .html) e ['timer_gettime()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_gettime.html). Le funzioni 'getitimer()' e 'setitimer()' non svaniranno immediatamente, ma la scrittura è sul muro. –

+0

OTOH, Mac OS X 10.10.4 non ha né 'timer_settime() 'né' timer_gettime() ', ma ha' getitimer() 'e' setitimer() '. Quindi le funzioni "obsolescenti" hanno la disponibilità dalla loro parte. Commenti simili si applicano a 'gettimeofday()' e 'clock_gettime()' - Mac OS X ha il primo ma POSIX preferisce quest'ultimo e ha contrassegnato il primo come obsoleto. –

1

Per audio/video in genere non sono necessari timer di precisione nano/micro secondi, è sufficiente un millisecondo. L'intervallo tra pacchetti più comune nell'audio è 20 ms. È ovvio usare nanosleep per questo scopo.

Inoltre, a meno che non si utilizzi il sistema operativo in tempo reale, non è possibile garantire tempi così buoni dal kernel.

La trappola di utilizzare il sonno nelle comunicazioni in tempo reale è: non mantengono la frequenza appropriata (50Hz per l'audio con intervallo di 20 ms). Perché su ogni tick si aggiunge il tempo di elaborazione all'intervallo di sospensione. Quindi l'intervallo di sonno deve essere calcolato sulla base del timestamp del tick precedente e del timestamp del tick successivo previsto.

È possibile implementare un timer ad intervalli brevi (ad esempio 10 ms) con sleep ed eventi di processo che dovrebbero verificarsi tra gli allarmi di questo timer sugli allarmi del timer. Se lo fai, ottimizzerai l'utilizzo delle risorse del sistema operativo (riducendo al minimo il cambio di contesto di processi/thread).

Problemi correlati