Linux, timerfd Genauigkeit
Ich habe ein system, dass braucht mindestens 10 mseconds der Genauigkeit für Timer.
Ich ging für timerfd wie es mir passt perfekt, aber festgestellt, dass sogar für Zeiten bis zu 15 Millisekunden, es ist nicht richtig überhaupt, entweder das, oder ich verstehe nicht, wie es funktioniert.
Den ich mal gemessen habe waren bis zu 21 mseconds auf 10 mseconds timer.
Ich habe zusammen ein schneller test zeigt, dass mein problem ein.
Hier ein test:
#include <sys/timerfd.h>
#include <time.h>
#include <string.h>
#include <stdint.h>
int main(int argc, char *argv[]){
int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
int milliseconds = atoi(argv[1]);
struct itimerspec timspec;
bzero(&timspec, sizeof(timspec));
timspec.it_interval.tv_sec = 0;
timspec.it_interval.tv_nsec = milliseconds * 1000000;
timspec.it_value.tv_sec = 0;
timspec.it_value.tv_nsec = 1;
int res = timerfd_settime(timerfd, 0, &timspec, 0);
if(res < 0){
perror("timerfd_settime:");
}
uint64_t expirations = 0;
int iterations = 0;
while( res = read(timerfd, &expirations, sizeof(expirations))){
if(res < 0){ perror("read:"); continue; }
if(expirations > 1){
printf("%lld expirations, %d iterations\n", expirations, iterations);
break;
}
iterations++;
}
}
Und ausgeführt so:
Zack ~$ for i in 2 4 8 10 15; do echo "intervals of $i milliseconds"; ./test $i;done
intervals of 2 milliseconds
2 expirations, 1 iterations
intervals of 4 milliseconds
2 expirations, 6381 iterations
intervals of 8 milliseconds
2 expirations, 21764 iterations
intervals of 10 milliseconds
2 expirations, 1089 iterations
intervals of 15 milliseconds
2 expirations, 3085 iterations
Selbst wenn einige Verzögerungen, 15 Millisekunden Verzögerungen klingt zu viel für mich.
Meine Daten über das Gebiet sind ziemlich rostig. Sounds, die Sie wollen, etwas zu tun, in Echtzeit. Überprüfen Sie Echtzeit-Linux-Versionen. Ansonsten scheduler verwendet mehr granularities zur Vermeidung höherer overhead. Sie möchten, um Ihre Geschäftsprozesse als ein RT (real-time) ein (
Danke für den Tipp, aber ich denke nicht, dass 20 Millisekunden-Intervallen als Teil der RT-Domäne. Ich meine, ein standard-system, wird gebeten, zu warten, für 10 Millisekunden sollten nicht warten, 21 Millisekunden), RT klingt viel zu sehr.
Sie könnten versuchen Sie, Ihr Programm mit realtime-Priorität, die Sie wahrscheinlich nicht verwenden müssen, die RT-Linux-kernel mainline ist ziemlich gut in Echtzeit in diesen Tagen und angesichts der Tatsache, dass es nie vermisst, mehr als ein Ablauf nur laufen mit RT-Priorität sollte es sein, genug, um Sie zu verpassen Sie nie eine
auch sollten Sie überlegen, Wetter oder nicht Sie absolut nicht vertragen können, fehlt ein Wake-up, wenn Sie verpassen können, manchmal, Mach dir keine sorgen, es wird passieren, aber es ist nicht das Ende der Welt, Sie werden bekommen die die meisten von Ihnen, obwohl. Bei mir läuft es auf meinem system und es hat nicht verpasst ein timer auf der 4ms-Schleife noch, und ich habe ausgeführt für eine Weile jetzt...
Jimenez: Echtzeit verweist, von strengen Anforderungen, nicht auf tatsächliche untere Grenze an die Genauigkeit. Es gibt viele, viele Dinge, die Wirkung der Aktualität der timer Lieferung, einschließlich der version von Linux (kernel) Sie verwenden, kann die Konfiguration mit kompiliert wurde, die hardware, die Sie verwenden, und was sonst noch auf dem system ausgeführt wird.
man sched_setparam
) und vermutlich auch unter root. Für die normalen Abläufe (z.B. Spiele-oder multimedia -) du hast (1) wartet in der engen Schleife oder (2) an jedem timer-Ereignis die Berechnung der Fehler (voraussichtlich v. aktuelle wake-up-Zeit) und nehmen Sie es in das Konto bei der Weiterentwicklung der internen Zeit-abhängigen Staat.Danke für den Tipp, aber ich denke nicht, dass 20 Millisekunden-Intervallen als Teil der RT-Domäne. Ich meine, ein standard-system, wird gebeten, zu warten, für 10 Millisekunden sollten nicht warten, 21 Millisekunden), RT klingt viel zu sehr.
Sie könnten versuchen Sie, Ihr Programm mit realtime-Priorität, die Sie wahrscheinlich nicht verwenden müssen, die RT-Linux-kernel mainline ist ziemlich gut in Echtzeit in diesen Tagen und angesichts der Tatsache, dass es nie vermisst, mehr als ein Ablauf nur laufen mit RT-Priorität sollte es sein, genug, um Sie zu verpassen Sie nie eine
auch sollten Sie überlegen, Wetter oder nicht Sie absolut nicht vertragen können, fehlt ein Wake-up, wenn Sie verpassen können, manchmal, Mach dir keine sorgen, es wird passieren, aber es ist nicht das Ende der Welt, Sie werden bekommen die die meisten von Ihnen, obwohl. Bei mir läuft es auf meinem system und es hat nicht verpasst ein timer auf der 4ms-Schleife noch, und ich habe ausgeführt für eine Weile jetzt...
Jimenez: Echtzeit verweist, von strengen Anforderungen, nicht auf tatsächliche untere Grenze an die Genauigkeit. Es gibt viele, viele Dinge, die Wirkung der Aktualität der timer Lieferung, einschließlich der version von Linux (kernel) Sie verwenden, kann die Konfiguration mit kompiliert wurde, die hardware, die Sie verwenden, und was sonst noch auf dem system ausgeführt wird.
InformationsquelleAutor Arkaitz Jimenez | 2010-06-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Versuchen Sie ändern es wie folgt, das sollte ziemlich viel garuntee, dass Sie ' ll verpassen Sie nie eine wakeup, aber vorsichtig sein, da läuft realtime-Priorität können sperren Sie Ihre Maschine schwer, wenn es nicht schläft, auch können Sie brauchen, um die Dinge so einzurichten, so dass Ihre Benutzer die Möglichkeit hat, zu laufen, Sachen zu realtime-Priorität (siehe
/etc/security/limits.conf
)Wenn Sie die Verwendung von threads, die Sie verwenden sollten
pthread_setschedparam
stattsched_setscheduler
.Realtime auch nicht über die niedrige Latenz, es geht um Garantien, RT bedeutet, dass, wenn Sie aufwachen wollen, genau einmal in jeder zweiten auf der zweiten, Sie, die normale Planung nicht geben Sie dazu entscheiden, um Sie aufwachen, 100ms später, denn es hatte noch andere arbeiten zu tun, die Zeit sowieso. Wenn Sie aufwachen wollen alle 10ms und Sie WIRKLICH tun müssen, dann sollten Sie sich zum ausführen als ein Echtzeit-task dann die kernel-wecken Sie alle 10ms ohne fehl. Es sei denn, eine höhere Priorität Echtzeit-task beschäftigt ist, Zeug zu tun.
Wenn Sie brauchen, um zu garantieren, dass Ihre wakeup-Intervall ist genau das, einiger Zeit ist es egal, ob es 1 MS oder 1 Sekunde, werden Sie nicht bekommen, es sei denn, Sie führen Sie als ein Echtzeit-task. Es gibt gute Gründe, den kernel tun dies, um Sie (Energie sparen ist einer von Ihnen, ein höherer Durchsatz ist eine andere, es gibt auch andere), aber es ist gut innerhalb seiner Rechte zu tun, da Sie nie gesagt, Sie müssen Sie besser garantiert. Die meisten Sachen nicht wirklich brauchen, um dies korrekt oder müssen nie verpassen, so sollten Sie darüber nachdenken, ob oder nicht Sie wirklich benötigen.
Zitat aus http://www.ganssle.com/articles/realtime.htm
Soft realtime ist so ziemlich das gleiche, außer das fehlende eine Frist, während unerwünscht ist, ist nicht das Ende der Welt (zum Beispiel video-und audio-Wiedergabe sind soft-realtime Aufgaben, die Sie nicht verpassen möchten die Anzeige einen Rahmen, oder laufen die out-of-Puffer, aber wenn Sie tun, es ist nur eine momentane hiccough, und Sie einfach weiter). Wenn das, was Sie zu tun versuchen, ist 'weicher' Echtzeit ich würde nicht die Mühe mit dem laufen im realtime-Priorität, da sollten Sie in der Regel erhalten Sie Ihr fest in der Zeit (oder zumindest nahe dran).
EDIT:
Wenn Sie das nicht-realtime-kernel wird standardmäßig geben alle Timer, die Sie machen etwas 'Locker', so dass es Zusammenführen können, Ihren Wunsch zu wecken, mit anderen Ereignissen, die zufällig mal in der Nähe, die Sie verlangt (das ist, wenn die andere Veranstaltung ist innerhalb Ihrer 'Locker' Zeit, es wird nicht aufwachen Sie an die Zeit, die Sie gefragt, aber ein wenig früher oder später, zur gleichen Zeit, es war schon etwas anderes zu tun, dies spart Strom).
Für ein wenig mehr info siehe Hoher (aber nicht zu hoher) Auflösung timeouts und Timer slack (Hinweis: ich bin nicht sicher, ob eines dieser beiden Dinge ist genau das, was wirklich in den kernel, da beide Artikel über die lkml Mailinglisten-Diskussionen, aber so etwas wie die erste wirklich in den kernel.
InformationsquelleAutor Spudd86
Ich habe das Gefühl, dass dein test ist sehr abhängig von der hardware. Bei mir lief dein Beispiel-Programm auf meinem system, es schien zu hängen bei 1ms. Um Ihren test überhaupt sinnvoll auf meinem computer, ich hatte zu ändern, von Millisekunden bis Mikrosekunden. (Ich habe die Vermehrer von 1_000_000 zu 1_000.)
(Etwas interessant, dass ich die längste läuft vom 16 und 47 Mikrosekunden, aber 17 und 48 waren schrecklich.)
Zeit(7) hat einige Vorschläge auf, warum unsere Plattformen sind so unterschiedlich:
Alle die 'Auflösung' - Zeilen in meiner /proc/timer_list sind 1ns auf meine (zugegeben lächerlich mächtig) x86_64 system.
Ich beschlossen, zu versuchen, um herauszufinden, wo der 'breaking point' ist auf meinem computer, aber habe bis auf 110 Mikrosekunden ausführen:
90 Mikrosekunden lief für drei Millionen Iterationen, bevor es nicht ein paar mal; das ist 22-mal bessere Auflösung als bei Ihrem ersten test, also würde ich sagen, dass angesichts die richtige hardware, 10ms sollte nicht irgendwo in der Nähe schwierig. (90 Mikrosekunden ist 111-mal bessere Auflösung als 10 Millisekunden.)
Aber wenn die hardware nicht die Timer für Zeitgeber mit hoher Auflösung, dann Linux können nicht helfen, Sie ohne Rückgriff auf SCHED_RR oder SCHED_FIFO. Und selbst dann vielleicht ein anderer kernel könnte besser bieten Ihnen mit der software-timer-Unterstützung, die Sie brauchen.
Glück. 🙂
InformationsquelleAutor sarnold
Hier ist eine Theorie. Wenn HZ ist auf 250 eingestellt, die für Ihr system ( wie typisch ) dann haben Sie ein 4-Millisekunden-timer-Auflösung. Sobald Ihr Prozess ist ausgelagert, die durch den scheduler, ist es wahrscheinlich, dass eine Reihe anderer Prozesse werden geplant und ausgeführt werden, bevor Sie Ihren Prozess bekommt eine andere Zeitscheibe. Das könnte auch erklären, Sie zu sehen-timer Beschlüsse der 15-bis 21 Millisekunden-Bereich. Der einzige Weg dies zu umgehen wäre, um führen Sie einen Echtzeit-kernel.
Typische Lösung für hochauflösende timing auf nicht-Echtzeit-Systemen ist grundsätzlich zu beschäftigt, warten mit einem Anruf zu wählen.
Mainline-Linux IST ein Echtzeit-system in diesen Tagen, es ist, dass nicht viele Leute wissen es 😛 (gut, es KANN sein, wenn Sie schreiben Sie Ihren code, um die Vorteile der realitme Funktionen)
InformationsquelleAutor Robert S. Barnes
Je nachdem, was das system tut, es kann ein bisschen langsam im Umschalten zurück zu Ihrer Aufgabe. Es sei denn, Sie haben eine "echte" realtime-system, es gibt keine Garantie, es wird nicht besser, als das, was Sie sehen, obwohl ich bin damit einverstanden, dass das Ergebnis ein wenig enttäuschend.
Können Sie (meistens) beseitigen, task-switch /Planer Zeit. Wenn Sie CPU-Leistung (und Strom!) zu ersparen, eine brutale, aber effektive Lösung wäre ein busy wait spin loop.
Die Idee ist, um das Programm auszuführen in einer engen Schleife, die ständig die Umfragen die Uhr, welche Zeit es ist, und ruft dann Ihre anderen code, wenn die Zeit reif ist. Auf Kosten der, dass dein system wirken sehr träge für alles andere und Heizung Ihre CPU, werden Sie am Ende mit dem task-scheduling, die meist jitter frei.
Schrieb ich dieses system schon einmal unter Windows XP zu Spinnen, ein Schrittmotor, liefert gleichmäßig beabstandeten Impulsen bis zu 40K mal pro Sekunde, und es funktionierte gut. Natürlich kann Ihre Laufleistung variieren.
InformationsquelleAutor Carl Smotricz