Pause (Sleep, Delay, Wait, ...) im Bereich von 1.5ms?



  • Hallo zusammen ...

    Ich hab hier ein Programm, welches zwei Ereignisse auslösen soll, diese müssen ziemlich exakt 1.5ms auseinander liegen. Das Problem ist zudem, dass das ganze in einer Schleife passiert, und die 1.5ms nicht nur exakt, sondern auch reproduzierbar sein sollen. Damit meine ich Abweichungen <100µs.

    Funktionen wie Sleep fallen weg, da sie zum einen zu grob sind und scheinbar auch viel zu ungenau.
    Das Problem ist sicher nicht neu, und ich hab auch schon ein, zwei Sachen dazu gefunden, aber so richtig hat bis jetzt nix funktioniert 😃

    Ich würde mich über einen guten Tipp sehr freuen 🙂

    PS: Ich arbeite übrigens unter Windows.



  • Unter Windosw ist das mit Betriebssystemmitteln schwierig, da es kein Realtime-fähiges sleep gibt.

    Was man aber machen kann, ist, eine Soundkarte (sofern vorhanden) als Taktgeber zu benutzen.
    Hierzu würde ich empfehlen, eine Lib wie zum Beispiel Portaudio zu benutzen, da diese den Zugriff auf die Hardware erheblich vereinfachen.
    Die API erwartet einen Callback, der dann vom Multimediabackend (zum Beispiel DirectSound) zyklisch und auf Grundlage der eingestellten Blocklänge und Abtsatrate aufgerufen wird.

    Wenn Du zum Beispiel für einen Audiokanal eine Abtastrate von 44.1 kHz und eine Blockgröße von 66 Samples einstellst, dann wird der Callback alle 1.49 ms aufgerufen.
    Ist nicht schön, aber unter Windows eine relativ gute Möglichkeit eine halbwegs brauchbare und jitterfreie Taktung zu bekommen.

    PS: Wenn jemand noch eine bessere Möglichkeit kennt, welche die CPU nicht zu großen Teilen auslastet, wäre ich übrigens auch dankbar dafür.



  • Tachyon schrieb:

    PS: Wenn jemand noch eine bessere Möglichkeit kennt, welche die CPU nicht zu großen Teilen auslastet, wäre ich übrigens auch dankbar dafür.

    Eine käufliche, aber dafür sehr präzise ist z.B.
    http://www.kithara.de/de/loesungen/echtzeit-timer



  • @Tachyon
    Guter Tip mit der Soundkarte!

    Wobei ja immer noch das Problem bleibt dass Windows nicht echtzeitfähig ist, und es sein kann dass der Thread viel später aufwacht als er sollte. 100µs sind da schon ein ziemlich ehrgeiziges Ziel.

    Hast du diesbezüglich mal Messungen gemacht?

    @Mandel
    Soll das auf Systemem laufen deren Hardware, installierte Treiber etc. unter deiner Kontrolle stehen? Oder soll/muss es auf beliebigen Systemen laufen?
    Mit "ausgesuchter" Hardware + Treibern wird es vielleicht ganz gut gehen.
    "Auf beliebigen Systemen" wird's aber eher nicht spielen. Google einfach mal nach "windows DPC latency spikes" (ohne "").



  • Also das System steht schon unter meiner Kontrolle. Allerdings wäre es ungünstig darann all zu viel zu ändern. Auf Zusatzhardware und kommerzielle Software möchte ich zumindest vorerst verzichten...



  • eine Alternative kann - sofern Du Windows verwendest - das Pollen mit QueryPerformanceCounter() sein, das löst aber nicht das von hustbär erwähnte Problem des verspäteten Threadaufwachens und ist sehr CPU-lastig.



  • hustbaer schrieb:

    @Tachyon
    Guter Tip mit der Soundkarte!

    Hmm, anscheinend nicht. Ich habe mal ein kleines Testprogramm geschrieben, um das Zeitverhalten genauer zu untersuchen. Dabei ist herausgekommen, dass der Callback teilweise in Bursts (also ohne messbaren Zeitabstand) und dann darauf folgend mit den windows-typischen 10ms Delays aufgerufen wird. Im Mittel stimmt das Zeitverhalten, aber der Jitter ist absolut grausam.


Anmelden zum Antworten