Minimale Zeit, die ein Thread in Linux pausieren kann

8

In meiner Anwendung müssen Threads für eine sehr kurze Zeit angehalten werden (100s Taktzyklen). Eine Möglichkeit zum Anhalten ist das Anrufen von Nanoschlaf, aber ich nehme an, es erfordert einen Systemaufruf an den Kernel. Jetzt möchte ich pausieren, ohne zum Kernel zu gehen.

Beachten Sie, dass ich genug Kerne habe, um meine Threads laufen zu lassen, und ich jeden Thread an einen separaten Kern anbinde, so dass sogar eine Anweisung, die den Kern für eine kurze Zeit anhalten kann, gut wäre. Ich benutze x86. Ich möchte nur, dass der Thread anhält, während ich pausiere. Ich möchte keine ausgelastete Schleife oder einen Systemaufruf an den Kernel. Ist es möglich, dies zu tun? Wie lange kann ich einen Thread pausieren?

    
MetallicPriest 10.09.2011, 13:03
quelle

6 Antworten

7

_mm_pause in einer Busy-Wait-Schleife ist der richtige Weg.

Leider kann sich die Verzögerung mit jeder Prozessorfamilie ändern:

Ссылка

Beispiel Verwendung für GCC unter Linux:

%Vor%

Kompilieren mit MMX aktiviert:

%Vor%

Sie können auch immer Inline-Assembler verwenden:

%Vor%

Von einigen Intel-Ingenieuren finden Sie das möglicherweise hilfreich, um die Kosten für das Pausieren zu ermitteln:

  

Der NOP-Befehl kann zwischen 0,4-0,5 Takten und dem PAUSE-Befehl liegen   kann 38-40 Uhren verbrauchen.

Ссылка

    
Steve-o 10.09.2011, 13:46
quelle
0

Es hängt davon ab, was Sie mit Pause meinen. Wenn Sie den Thread für eine kurze Zeit anhalten möchten, kann dies nur vom Betriebssystem ausgeführt werden.

Wenn Sie jedoch eine kurze Verzögerung wünschen, können Sie dies mit einer aktiven Schleife tun. Das Problem bei der Verwendung einer solchen Schleife ist, dass Sie nicht wissen, wie lange es wirklich läuft. Sie können es schätzen, aber ein Interrupt kann es länger machen.

    
Peter Lawrey 10.09.2011 13:47
quelle
0

Im Allgemeinen würde ich für solch eine kurze Verzögerung denken, dass ein Systemanruf nicht praktikabel ist, weil der Overhead von Systemanruf + Scheduling + Kontextwechsel und zurück wieder viel länger ist als Ihre Pause, wie Sie scheinen schon bewusst sein.

Was übrig bleibt, ist zu drehen (beschäftigt warten), um die Verzögerung zu erzeugen. Sie können das Lesen von TSC-Werten wiederholen, um beispielsweise zu erfahren, wie viel rotiert wird (oder anwendbares Zykluszähler-Register für andere Prozessoren)

Ja, wenn man so rotiert, wird Energie verschwendet, und wenn man auf einer CPU mit mehreren Hardware-Threads läuft, wie es Multi-Core normalerweise annimmt, nehmen Sie auch Execution Slots von den anderen Threads unnötig, aber wenn Sie nicht sehr sehr haben sehr niedriger Overhead-System-Aufruf und Scheduler-Mechanismus und ein High-Res-Timer, würde ich sagen, dass es nicht möglich ist.

    
gby 10.09.2011 14:38
quelle
0

Warum drehst du dich nicht einfach selbst? Sie können in einer Schleife die Anweisung rdtsc wiederholt aufrufen, um die Anzahl der Taktzyklen abzurufen, und dann einfach anhalten, wenn die Differenz 100 Taktzyklen überschreitet.

Ich nehme an, es ist für ein Handelssystem, für das dies eine übliche Technik ist

    
Foo Bah 10.09.2011 16:11
quelle
-1

nein - das ist nicht möglich. Entweder rufen Sie sleep oder select - kernel an; oder eine Schleife haben, verschwenden Zeit.

    
Ed Heal 10.09.2011 13:07
quelle
-2

Ihre einzige Hoffnung, das genaue Timing zu bekommen, ist die Verwendung von timer_create und das Ablaufen des Timer-Ablaufs durch ein Signal, denke ich. Mit Echtzeitplanung.

Ich bin mir nicht sicher, wofür es möglicherweise nützlich sein könnte, da Sie in einem so kleinen Zeitfenster kein IO ausführen können und es daher keine Rolle spielt, ob Ihr Code 1000 Mal mit einer Lücke von 100ns zwischen jedem Durchlauf ausgeführt wird oder 1000 mal alles zusammen mit einer 100ms Lücke am Ende.

    
R.. 10.09.2011 14:01
quelle

Tags und Links