Der beste Weg, um einen Thread zu verlangsamen? Verwendet Sleep () OK?

8

Ich habe eine C ++ - Bibliothek geschrieben, die eine ziemlich schwere CPU-Arbeit erledigt (alles Mathematik und Berechnungen) und wenn sie auf ihre eigenen Geräte angewiesen ist, wird sie 100% aller verfügbaren CPU-Ressourcen verbrauchen (sie ist auch Multithread-fähig) der verfügbaren logischen Kerne auf der Maschine).

Als solches habe ich einen Callback innerhalb der Haupt-Berechnungsschleife, die Software, die die Bibliothek verwendet, aufrufen soll:

%Vor%

Im Rückruf ruft der Client Sleep (x) auf, um den Thread zu verlangsamen.

Ursprünglich war der clientseitige Code ein fester Sleep (100) -Aufruf, aber dies führte zu einer schlechten, unzuverlässigen Leistung, da einige Rechner die Berechnungen schneller als andere beendeten, aber der Ruhezustand auf allen Maschinen gleich ist. Jetzt überprüft der Client die Systemzeit, und wenn mehr als 1 Sekunde vergangen ist (was == mehrere Iterationen), wird es für eine halbe Sekunde schlafen.

Ist das eine akzeptable Methode, einen Thread zu verlangsamen? Sollte ich einen Semaphor / Mutex anstelle von Sleep () verwenden, um die Leistung zu maximieren? Schläft x Millisekunden für jede 1 Sekunde Verarbeitung gut oder gibt es etwas falsch, das ich nicht bemerke?

Der Grund, warum ich frage, ist, dass die Maschine immer noch schwer festsitzt, obwohl der Taskman zeigt, dass der Prozess ~ 10% der CPU beansprucht. Ich habe bereits Festplatten- und Speicherkonflikte vergeblich untersucht, also frage ich mich jetzt, ob die Art, wie ich den Thread verlangsame, dieses Problem verursacht.

Danke!

    
Mahmoud Al-Qudsi 17.01.2010, 15:25
quelle

5 Antworten

2

Schlaf sollte in Ordnung sein, um eine App zu drosseln, die aus deinen Kommentaren stammt. Vielleicht müssen Sie nur präzisieren, wie lange Sie schlafen.

Die einzige Software, in der ich eine Funktion wie diese verwende, ist der BOINC-Client . Ich weiß nicht, welchen Mechanismus es verwendet, aber es ist Open-Source-und Multi-Plattform, also hilf dir selbst.

Es hat eine Konfigurationsoption ("Begrenzung der CPU auf X%"). Die Art, wie ich dies implementieren würde, ist die Verwendung plattformabhängiger APIs wie clock() oder GetSystemTimes() und vergleiche die Prozessorzeit mit der verstrichenen Wanduhrzeit. Machen Sie ein bisschen echte Arbeit, prüfen Sie, ob Sie über- oder unterdurchschnittlich sind, und ob Sie für eine Weile übermäßig schlafen, um wieder unterzukommen.

Der BOINC-Client spielt sich gut mit Prioritäten ab und verursacht auch bei 100% maximaler CPU keine Performance-Probleme für andere Apps. Der Grund, warum ich den Gashebel benutze, ist, dass der Client ansonsten die CPU ständig flattert und die Lüftergeschwindigkeit und das Rauschen erhöht. Ich betreibe es also auf der Ebene, wo der Lüfter ruhig bleibt. Bei besserer Kühlung würde ich es vielleicht nicht brauchen :-))     

Steve Jessop 17.01.2010, 15:43
quelle
23

Warum verwenden Sie keine niedrigere Priorität für die Berechnungsthreads? Das stellt sicher, dass andere Threads geplant werden, während Ihre Berechnungsthreads so schnell wie möglich ausgeführt werden können, wenn keine anderen Threads ausgeführt werden müssen.

    
Brian Rasmussen 17.01.2010 15:28
quelle
4

Was ist falsch an der CPU bei 100%? Das solltest du anstreben, nicht versuchen zu vermeiden. Diese mathematischen Berechnungen sind wichtig, nicht? Wenn Sie nicht versuchen, eine andere Ressource zu meiden, die nicht explizit vom Betriebssystem verwaltet wird (Mutex, Festplatte usw.) und vom Hauptthread verwendet wird, ist es generell eine schlechte Idee, den Thread zu verlangsamen. Was ist mit Multicore-Systemen (die fast alle Systeme haben werden)? Sie würden einen Thread für absolut keinen Grund verlangsamen.

Das Betriebssystem hat ein Konzept eines Thread-Quantums. Es wird dafür sorgen, dass kein wichtiger Thread auf Ihrem System ausgehungert wird. Und, wie ich bereits erwähnt habe, schadet Multicore-Systemen, die einen Thread auf einer CPU spiked, die Leistung für andere Threads in anderen Kernen überhaupt nicht.

Ich sehe auch in einem anderen Kommentar, dass dieser Thread auch eine Menge Festplatten-I / O macht - diese Operationen werden Ihren Thread bereits dazu bringen, nachzugeben, während er auf die Ergebnisse wartet, so dass die Betten nichts tun.

Wenn Sie Sleep (x) aufrufen, ist im Allgemeinen etwas falsch / faul mit Ihrem Design. Wenn Sie x == 0 wählen, öffnen Sie sich selbst für Live-Sperren (der Thread, der Sleep (0) aufruft). kann sofort verschoben werden, so dass es ein Noop).

    
Terry Mahaffey 17.01.2010 17:50
quelle
0

Eine andere, nicht so ausgeklügelte Methode könnte darin bestehen, eine Iteration zeitlich zu bestimmen und den Thread für (x * t) Millisekunden vor der nächsten Iteration schlafen zu lassen, wobei t die Millisekunde Zeit für eine Iteration und x der gewählte Schlafzeitbruch ist ( zwischen 0 und 1).

    
user153062 17.01.2010 16:14
quelle
0

Sehen Sie sich cpulimit an. Er sendet SIGSTOP und SIGCONT nach Bedarf, um einen Prozess unterhalb eines bestimmten CPU-Auslastungsprozentsatzes zu halten.

Sogar noch, WTF bei "verrückten Beschwerden und ausgefallenen Rezensionen über Ihre Software, die PC-Leistung tötet". Ich würde mich eher beschweren, dass Ihre Software langsam ist und meine Hardware nicht optimal nutzt, aber ich bin nicht Ihr Kunde.

Bearbeiten: Unter Windows können SuspendThread() und ResumeThread() wahrscheinlich ein ähnliches Verhalten erzeugen.

    
P-Nuts 17.01.2010 15:53
quelle