Hallo. Ich habe für Testzwecken ein Programm geschrieben, was mit variabler Thread-Anzahl ein oder mehrere Cores zu 100% auslastet. Wenn ich also 4 Cores habe und 75% Auslastung erzeugen will dann erstelle ich eben 3 Threads, wodurch 3 Cores zu 100% ausgelastet sind und die Systemlast entsprechend 75% beträgt. Nun ist es aber so, dass wenn ich nur einen Core habe, die CPU-Last immer 100% ist. Jetzt würde ich gerne versuchen meinen Thread so zu modifizieren, dass er kurzzeitig, je nach gewünschter Auslastung, die Rechenzeit wieder freigibt, sodass ich auch z.B. eine Auslastung von 63% erzeugen kann. Mit Sleep() geht das nicht, weil da die Auflösung nur etwa 15,6ms beträgt was natürlich viel zu lang ist. Alle anderen Warteschleifen geben jedoch die Rechenzeit nicht wieder frei. Gibt es da eine Möglichkeit das irgendwie hinzubekommen?
warum sollte man sotwas überhaupt machen? Was heist überhaupt 100% auslasung. Wenn die CPU nicht zu tun hat denn schläft sie. Sie wird also runter getaktet. Bezieht sich die 100% nun auf die maximale Leistung der CPU oder auf die Leistung die sie zu diesem Zeitpunkt hat?
Peter schrieb: > warum sollte man sotwas überhaupt machen? Es geht darum, einem anderen Prozess gezielt eine gewisse CPU-Rechenzeit zu "stehlen" um zu sehen welche Auswirkungen das hat. > Wenn die CPU nicht zu tun hat denn schläft sie. Sie wird also > runter getaktet. Das passiert nur wenn 1. die CPU das unterstützt und zweitens wenn es auch aktiviert ist. Das ist bei mir jedoch nicht der Fall. > Bezieht sich die 100% nun auf die maximale Leistung der > CPU oder auf die Leistung die sie zu diesem Zeitpunkt hat? Auf die maximale Leistung der CPU. Mit meinem Programm schaffe ich es die 2x80W TDP von zwei Intel Xeon E5530 ziemlich genau zu erreichen, demnach arbeiten die Recheneinheiten der CPU schon sehr intensiv.
Timmo H. schrieb: >> warum sollte man sotwas überhaupt machen? > Es geht darum, einem anderen Prozess gezielt eine gewisse CPU-Rechenzeit > zu "stehlen" um zu sehen welche Auswirkungen das hat. aber selbst wenn du die CPU zu 100% auslastest, geht ja immer noch einiges. Also lastest du sie ja nicht zu 100% aus. Wenn du die gleiche Priorität wie der andere Prozess hast. Dann schaffst du auch nur eine 50% Auslastung selbst wenn du ohne sleep nur eine schleife machst.
Um das zu erreichen musst erst einmal herausfinden wieviele "Last-Anweisungen" dein Programm auf der CPU maximal hinbekommt in einem bestimmten Zeitraum. Wenn das z.B. 10 pro Sekunde sind und du willst 50% Auslastung dann lässt du eine "Last-Anweisung" laufen, dann eine Pause von der Länge einer "Last-Anweisung", dann ...
Timmo H. schrieb: > Mit Sleep() geht das nicht, weil da die Auflösung nur etwa 15,6ms > beträgt was natürlich viel zu lang ist. Die Granularität des Windows-Schedulers beträgt 10 msec und lässt sich auch auf 1 msec reduzieren. Das geht mit der Multimedia-Funktion timeBeginPeriod Beitrag "Re: Phänomen: Software schneller, wenn Media-Player läuft!"
Also eigentlich würde mir ein Sleep_us() ja schon was bringen, aber das gibts halt nicht. Zumal Windows eben auch kein Echtzeit OS ist. Vielleicht stricke ich das alles nochmal um, sodass ich nicht ca. 20000 Durchläufe/s habe sondern nur noch 100 oder so, dann kann ich evtl. mit Sleep arbeiten. @Rufus Danke, das ist schonmal besser.
1 | void Throttle(DWORD percent) { |
2 | for (int i = 0; i < 10; i++) { |
3 | DWORD t = GetTickCount(); |
4 | while (GetTickCount() < t + percent) { |
5 | }
|
6 | Sleep(100 - percent); |
7 | }
|
8 | }
|
Sowas erzeugt hier relativ gut (+-5%) die entsprechende Last. Ansonsten QueryPerformanceFrequency, QueryPerformanceCounter und das schon erwähnte timeBeginPeriod Bei mehreren Cores/CPU kommen noch SetProcessAffinityMask und SetThreadAffinityMask hinzu.
Hallo Arc Net, das sieht doch schonmal gut aus, ich werde es morgen mal testen.
So ich habe es gerade mal getestet. Das funktioniert bis ca. 40% erstaunlich genau. Das reicht mir eigentlich schon. Danke schonmal dafür! Jetzt habe ich durch das Sleep jedoch ein Problem dazugewonnen, während des Sleeps kann Windows den Thread auf einen anderen Core auslagern, was es natürlich auch macht, sodass jeder Core im Schnitt etwa gleich stark ausgelastet ist. Klar nun könnte ich über den Taskmanager die Zugehörigkeit auf einen Core begrenzen. Jedoch wäre das Automatisch natürlich wesentlich komfortabler, vorallem bei einem 16-Core System :D Kann man das irgendwie bewerkstelligen?
Wie von Arc Net schon beschrieben geht das mit: SetProcessAffinityMask und SetThreadAffinityMask ;)
da gibt es tools für, google doch mal, mir fällt grad kein Name ein. Wenn du es selber machen willst, würde mir folgendes einfallen: so eine Art PWM, in der du das Tastverhältnis änderst: du suchst dir eine Zeiteinheit, zB 50ms Je nach gewünschter CPU-Auslastung x = 50*prozentualeAuslastung/100 sleep(50-x); // keine CPU-Belastung //timer aufsetzen, der in (x) ms flag setzt while(!flag){ // 100% CPU-Belastung } und das in Endlossschleife
Sid schrieb: > Wie von Arc Net schon beschrieben geht das mit: > SetProcessAffinityMask und SetThreadAffinityMask ;) Tatsache, hab ich doch glatt überlesen :D Vielen dank euch allen, ich denke das Problem ist gelöst.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.