Präzise Gewinde Schlaf benötigt. Max 1ms Fehler
Habe ich rote Faden, der loop.
Ich brauche, dass die Schleife einmal ausgeführt werden alle 5ms (1ms-Fehler).
Ich weiß, dass die Funktion Sleep() ist nicht präzise.
Haben Sie irgendwelche Vorschläge?
Update.
Ich kann es nicht anderen Weg.
Am Ende der Schleife brauche ich irgendeine Art von Schlaf.
Ich möchte nicht, dass zu 100% die CPU geladen.
Dies ist ein XY-problem. Was auch immer Sie wirklich brauchen, zu tun, wahrscheinlich gibt es einen Weg, es zu tun. Aber dies ist nicht der Weg. (Ansonsten, wenn das wirklich so ist was Sie tun müssen, widmen einen Kern in diesem thread, und spin für 5ms. Das system kann nicht sinnvoll andere Arbeit verrichten, für die kleinen einen Zeitraum von Zeit.)
Hat die threading-system, das wirklich geben Ihnen jede Art von Zeit garantiert? In der Tat, nicht das OS läuft bist du auf einmal bieten? Sofern Sie ein Betriebssystem ausführen, die tatsächlich gibt Ihnen jede Art von Echtzeit-Garantien (WinCE vermutlich nicht, weiß nicht, über andere Versionen von Windows), dann haben Sie möglicherweise nicht immer in der Lage sein, zu garantieren, dass der thread oder Prozess-scheduler nicht nur unterbrechen, Ihrer Aufgabe und Verwendung die CPU-Zeit für etwas anderes.
"Genau um 1ms" ist ein bisschen ein oxymoron.
Der Titel gibt den Fehler von 1ms, und die Frage gibt die Dauer von 5ms. Das ist ein Fehler von 20%. In meinem Buch, das ist nicht sehr präzise.
Gut, zu gehen zu halten, für das wohl der cache und die übrigen in Zeit die Kontrolle über die Scheibe ist eine gute Idee, Stimme ich zu. Aber wenn die Zeit ankommt, ist es schließlich auch Fragen zu anderen threads. Also es ist zumindest nicht klar, ob die holding der Faden, der sich durch das drehen ist besser als Verzicht auf die Erinnerung des threads Zeitscheibe. Caches sind riesig in diesen Tagen und die Zeit einer kritischen Anwendung sind in der Regel nicht nehmen viel Speicher, besonders wenn sich wiederholende Dinge, die in einem 5-ms-Periode. Ich selbst schlage
Hat die threading-system, das wirklich geben Ihnen jede Art von Zeit garantiert? In der Tat, nicht das OS läuft bist du auf einmal bieten? Sofern Sie ein Betriebssystem ausführen, die tatsächlich gibt Ihnen jede Art von Echtzeit-Garantien (WinCE vermutlich nicht, weiß nicht, über andere Versionen von Windows), dann haben Sie möglicherweise nicht immer in der Lage sein, zu garantieren, dass der thread oder Prozess-scheduler nicht nur unterbrechen, Ihrer Aufgabe und Verwendung die CPU-Zeit für etwas anderes.
"Genau um 1ms" ist ein bisschen ein oxymoron.
Der Titel gibt den Fehler von 1ms, und die Frage gibt die Dauer von 5ms. Das ist ein Fehler von 20%. In meinem Buch, das ist nicht sehr präzise.
Gut, zu gehen zu halten, für das wohl der cache und die übrigen in Zeit die Kontrolle über die Scheibe ist eine gute Idee, Stimme ich zu. Aber wenn die Zeit ankommt, ist es schließlich auch Fragen zu anderen threads. Also es ist zumindest nicht klar, ob die holding der Faden, der sich durch das drehen ist besser als Verzicht auf die Erinnerung des threads Zeitscheibe. Caches sind riesig in diesen Tagen und die Zeit einer kritischen Anwendung sind in der Regel nicht nehmen viel Speicher, besonders wenn sich wiederholende Dinge, die in einem 5-ms-Periode. Ich selbst schlage
Sleep(0)
zu verbessern timing. Und spinnging funktioniert nur zuverlässig bei hohen Priorität.InformationsquelleAutor Hooch | 2012-11-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sich aus der Frage, tags ich nehme an, du bist auf windows.
Werfen Sie einen Blick auf Multimedia-Timer, Sie werben für die Präzision unter 1ms.
Eine weitere Optionen ist die Verwendung Spin Locks aber das wird im Grunde halten Sie ein cpu-Kern bei maximaler Auslastung.
Außer eigene Dokumentation im "Wait-Funktionen und Time-out-Intervalle" der Zustand, "Wenn Sie rufen
timeBeginPeriod
nennen Sie es eine Zeit früh in der Anwendung und sicher sein, rufen Sie dietimeEndPeriod
Funktion ganz am Ende der Anwendung ist", denn "häufige Anrufe können erhebliche Auswirkungen auf die system-Uhr system-Stromverbrauch und der Planer". Also, wenn Sie je auf diese Genauigkeit für viele Anrufe, sollten Sie sich nicht anpassen, vor und nach jedem Anruf.Und da die
timeBeginPeriod
undtimeEndPeriod
Funktionen angezeigt zu ändern OS globalen Zustand (nicht nur für Ihren eigenen Prozess), und die docs scheinen zu implizieren, dass eintimeBeginPeriod
dass nicht abgestimmt durch einetimeEndPeriod
ist nicht fest, auch durch den Prozess der Tod, so scheint es wirklich einfach (z.B. segfaulting oder sonst schwer zu töten den Prozess, während die Uhr eingestellt ist), um versehentlich am Ende mit der system-Uhr in einem suboptimalen Zustand dauerhaft (oder zumindest bis zum Neustart). Wirklich schlecht für alles andere läuft auf eine Batterie, wo der erhöhte Stromverbrauch weh tut. Scheint nicht eine gute Idee im Allgemeinen.Ich bin verwirrt. Sie scheinen einverstanden mit dem, was ich schrieb, aber schreiben Sie so, als wäre es eine Widerlegung.
Ich war uneins nur mit "sicher sein, rufen Sie timeEndPeriod, sobald Sie Sie nicht mehr benötigen diese Präzision", denn das bedeutet, Sie könnten es verwenden, für feinkörnige Zwecke (Geschwindigkeit bis Uhr vor dem schlafen, verlangsamen Sie es nach), die ausdrücklich davor gewarnt. Ich gebe zu, deine Formulierung war ein wenig zweideutig ist (Sie bedeuten könnte ", wenn das Programm nie müssen, dass die Präzision wieder"), so könnte ich sprang die Pistole.
InformationsquelleAutor Marius
Nicht verwenden Spinnerei hier. Die angeforderte Auflösung und Genauigkeit kann erreicht werden mit standard-Methoden.
Können Sie verwenden
Sleep()
nach unten zu Perioden von etwa 1 ms, wenn die Systeme interrupt-Zeit ist so eingestellt, dass eine hohe Frequenz. Blick auf die Beschreibung des Sleep(), um die Einzelheiten, insbesondere die multimedia-Timer mit Beschaffung und Einstellung der Timer-Auflösung, um die details auf, wie die Systeme interrupt-Periode.Die erreichbare Genauigkeit mit solcher Ansatz ist in den wenigen Mikrosekunden-Bereich, wenn richtig umgesetzt.
Ich vermute, dein loop ist etwas anderes zu tun zu haben. Also ich vermute, Sie möchten eine Gesamt-Zeit von 5 ms, das wäre dann die Summe der
Sleep()
und den rest der Zeit verbringen Sie auf andere Dinge in der Schleife.Für dieses Szenario würde ich vorschlagen, dass Wartemöglichkeit Timer-Objekte, aber diesen Timer setzen ebenfalls auf die Einstellung der multimedia-timer-API. Ich habe eine übersicht über die relevanten Funktionen für höhere Präzision timing hier. Viel tieferen Einblick in hoher Präzision timing zu finden hier.
Für noch mehr genaue und zuverlässige Zeitmessung, die Sie haben können, um einen Blick in
process priority classes
undthread priorities
. Eine andere Antwort über die Sleep() die Genauigkeit ist diese.Jedoch, ob es möglich ist, erhalten Sie eine
Sleep()
Verzögerung von genau 5 ms, hängt von der Anlagen-hardware. Einige Systeme erlauben das betreiben von 1024 interrupts pro Sekunde (von der multimedia-timer-API). Dies entspricht einer Frist von 0.9765625 ms. Die nächstgelegene Sie bekommen können, so ist 4.8828125 ms. Andere erlauben es, dem näher zu kommen, vor allem, da Windows 7 das timing verbessert sich erheblich, wenn auf betrieben hardware, diehigh resolution event timers
. Sehen Über Timer bei MSDN und Der High Precision Event Timer.Zusammenfassung: Legen Sie den multimedia-timer für den Betrieb bei maximaler Frequenz und verwenden wartemöglichkeit timer.
InformationsquelleAutor Arno
Ich war auf der Suche für leichte cross-Plattform-Standby-Funktion, die geeignet ist für Echtzeit-Anwendungen (also hohe Auflösung/hohe Präzision mit Zuverlässigkeit). Hier sind meine Ergebnisse:
Scheduling Grundlagen
Aufzugeben CPU und dann immer wieder ist teuer. Nach dieser Artikel, scheduler Latenz irgendwo zwischen 10-30ms auf Linux. Also, wenn Sie brauchen, um zu schlafen weniger als 10ms mit hoher Präzision, dann müssen Sie verwenden spezielle OS-spezifische APIs. Die üblichen C++11 std::this_thread::sleep_for ist nicht mit hoher Auflösung schlafen. Zum Beispiel auf meiner Maschine, quick-tests zeigt, dass es oft schläft mindestens 3ms, wenn ich bitten es zu schlafen für nur 1ms.
Linux
Beliebteste Lösung zu sein scheint, nanosleep () - API. Allerdings, wenn Sie wollen < 2ms Schlaf mit hoher Auflösung, als Sie brauchen, verwenden Sie auch sched_setscheduler Aufruf zum festlegen der thread - /Prozess-für real-time scheduling. Wenn Sie nicht als nanosleep() verhält sich genau wie veraltet usleep hatte die Auflösung von ~10ms. Eine andere Möglichkeit ist die Verwendung Alarme.
Windows
Lösung ist hier die Verwendung von multimedia-mal, wie andere vorgeschlagen haben. Wenn Sie möchten, zu emulieren die Linux nanosleep() auf Windows, unten ist, wie (original ref). Wieder, beachten Sie, dass Sie brauchen nicht zu tun CreateWaitableTimer() und immer wenn der Aufruf sleep() im loop.
Cross-Plattform-Code
Hier ist die time_util.cc implementiert Schlaf für Linux -, Windows-und Apple-Plattformen. Jedoch feststellen, dass es nicht real-time-Modus mit sched_setscheduler wie ich oben erwähnte, also, wenn Sie verwenden möchten, für <2ms, dann ist das etwas, das Sie tun müssen, zusätzlich. Eine andere Verbesserung, die Sie machen können, ist zu vermeiden, fordern CreateWaitableTimer für die Windows-version über und über wieder, wenn Sie anrufen, schlafen in einigen Schleife. Für wie dies zu tun, siehe Beispiel hier.
Andere noch komplette cross-Plattform-code kann finden Sie hier.
Eine Andere Schnelle Lösung
Wie Sie vielleicht bemerkt haben, obige code ist nicht mehr sehr leicht. Es muss der Windows-header unter anderem Dinge, die vielleicht nicht sehr wünschenswert, wenn Sie die Entwicklung header-only-Bibliotheken. Wenn Sie brauchen, schlafen weniger als 2ms und Sie sind nicht sehr scharf auf mit OS-code, dann kann man nur folgende einfache Lösung, die ist cross-Plattform und arbeitet sehr gut auf meine Prüfungen. Denken Sie nur daran, dass Sie jetzt nicht mit stark optimierten OS-code, die vielleicht viel besser auf Energie sparen und verwalten von CPU-Ressourcen.
Fragen
InformationsquelleAutor Shital Shah
Anstatt zu schlafen, vielleicht können Sie versuchen, eine Schleife, die überprüft, das Zeitintervall und gibt, wenn die Zeit Differenz ist 5ms. Die Schleife sollte genauer sein, dann schlafen.
Beachten Sie jedoch, dass die Präzision ist nicht immer möglich. Die cpu könnte gebunden werden, die mit einem anderen Betrieb, für ein so kleines Intervall, und verpassen kann die 5 ms.
Ja, vielleicht bin ich old-school, aber es kann passieren, dass der Prozessor macht noch etwas anderes und findet die 1ms überprüfen. Es sollte getestet werden, unter Last etc, wenn der 1ms Anforderung entscheidend ist.
In der Tat, ein paar threads umgeschaltet werden kann, in einem in jener Zeit. blog.tsunanet.net/2010/11/...
Es ist eine option. Aber ich möchte eine CPU, einen rest für 5ms.
InformationsquelleAutor Kami
Diese Funktionen:
lassen, die Sie erstellen, eine wartemöglichkeit timer mit einer 100-Nanosekunden-Auflösung, warten Sie, und der aufrufende thread ausführen einer bestimmten Funktion bei trigger-Zeit.
Hier ist ein Beispiel für den Einsatz von Sprach-timer.
Beachten Sie, dass die WaitForSingleObject hat ein timeout, gemessen in Millisekunden, das könnte vielleicht funktionieren wie ein plumper Ersatz für die Wartezeit, aber ich würde nicht darauf Vertrauen. Sehen dies SO Frage für details.
InformationsquelleAutor didierc