2015-07-10 15 views
5

In C++ für Linux, ich versuche, jede Mikrosekunde/Nanosekunde etwas zu tun und verwende derzeit die NanoSleep-Funktion unten. Es funktioniert, aber wenn der Code millionenfach wiederholt wird, wird dies teuer. Ich suche nach einem hochauflösenden Timer, der ein sehr genaues Timing ermöglicht (die Anwendung ist Audio/Video). Irgendwelche Ideen?Auf der Suche nach einem hochauflösenden Timer

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

Irgendwas stimmt nicht mit ''? – chris

+2

Wenn Ihre CPU einen 4-GHz-Takt hat, haben Sie 4 Taktzyklen in einer Nanosekunde. Sie können nicht jede Nanosekunde sehr viel tun, selbst bei dieser Geschwindigkeit. –

+0

Von welcher Art von Linux und Prozessor reden wir? Für Nicht-Echtzeit-Systeme ist alles, was höher ist als die ms-Genauigkeit, schon ziemlich ambitioniert. Microsecond (nicht zu erwähnen, Nanosekunde) Genauigkeit ist etwas, was Sie nicht einmal auf den meisten Echtzeit-Systemen anstreben würden. – MikeMB

Antwort

4

Mit 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)); 
} 

Erinnern Sie sich mit -std=c++11 Flagge zu kompilieren.

+0

Ich habe die beiden Ansätze verglichen und sie scheinen sehr ähnlichen Rechenaufwand zu haben (der Systemaufruf dauert sehr lange). Ist das wirklich das Beste, was man tun kann, oder ist es möglich, einen speziellen Timer direkt aus dem Kernel zu verwenden? – Josh

+0

@Josh Ich denke, dass dies das Beste ist, was von der Benutzerseite aus getan werden kann. – Shreevardhan

0

Sie können Mikrosekunde Auflösung mit getitimer (2) erhalten:

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

+0

Beachten Sie, dass POSIX ['settimer()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/setitimer.html) und ['getitimer()'] (http: //pubs.opengroup) markiert .org/onlinepubs/9699919799/functions/gititimer.html) als veraltet und sagt, dass die bevorzugten Ersetzungsfunktionen ['timer_settime()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functs/timer_settime .html) und ['timer_gettime()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_gettime.html). Die Funktionen 'gititimer()' und 'settimer()' verschwinden nicht sofort, aber das Schreiben ist an der Wand. –

+0

OTOH, Mac OS X 10.10.4 hat weder 'timer_settime()' noch 'timer_gettime()', aber es hat 'gititimer()' und 'settimer()'. So haben die "veralteten" Funktionen Verfügbarkeit auf ihrer Seite. Ähnliche Kommentare gelten für 'gettimeofday()' und 'clock_gettime()' - Mac OS X hat das vorherige, aber POSIX bevorzugt das letztere und hat das erstere als veraltet markiert. –

1

Für Audio/Video in der Regel brauchen Sie keine Nano/Mikrosekunden Präzisions-Timer, Millisekunden ist genug. Das gebräuchlichste Interpaketzwischenintervall beträgt 20 ms. Es ist ok, NanoSleep für diesen Zweck zu verwenden.

Darüber hinaus können Sie nicht garantieren, dass Sie so gute Timings vom Kernel erhalten, wenn Sie kein Echtzeit-Betriebssystem verwenden.

Nachteil der Verwendung von Schlaf in Echtzeit-Kommunikation ist: sie halten nicht die entsprechende Frequenz (50Hz für Audio mit 20ms Intervall). Weil Sie bei jedem Tick Verarbeitungszeit zum Schlafintervall hinzufügen. Daher muss das Schlafintervall basierend auf dem vorherigen Tick-Zeitstempel und dem nächsten erwarteten Tick-Zeitstempel berechnet werden.

Sie können einen Kurzintervall-Timer (z. B. 10 ms) mit Schlafplätzen implementieren und Ereignisse verarbeiten, die zwischen diesen Timer-Alarmen bei Timer-Alarmen auftreten sollen. Wenn Sie dies tun, werden Sie die Nutzung der Betriebssystemressourcen optimieren (Minimierung des Prozess-/Thread-Kontextwechsels).

Verwandte Themen