delay und 100%ige Prozessorauslastung in while
-
Die folgende Schleife:
while (true) { }
erzeugt ja bekanntlich 100 % Prozessorauslastung. Wenn ich in Windows dort ein
Sleep(1)
einbaue, geht die Auslasung runter. Wie mache ich das gleiche in DOS? Die Funktionsleep
kann nur ganze Sekunden warten. Und die Funktiondelay
setzt die Auslastung nicht runter. Selbst wenn ich einen großen Wert einsetze:#include <dos.h> int main() { while (true) { delay(5000); } }
steht die Auslastung immer noch auf 100%. Wie kann ich das ändern? Welche Funktion muss man in DOS nehmen, um ein Minimum an Zeit zu warten und dadurch den Prozessor zu entlasten?
-
Gin Beam schrieb:
Die folgende Schleife erzeugt ja bekanntlich 100 % Prozessorauslastung.
Auf meinem Vierkerner nicht...
Gin Beam schrieb:
Die Funktion
sleep
kann nur ganze Sekunden warten.Nö, Millisekunden.
-
EOutOfResources schrieb:
Gin Beam schrieb:
Die folgende Schleife erzeugt ja bekanntlich 100 % Prozessorauslastung.
Auf meinem Vierkerner nicht...
Schön, dann eben 25%. Du weißt aber ganz genau, worauf ich hinaus will.
EOutOfResources schrieb:
Gin Beam schrieb:
Die Funktion
sleep
kann nur ganze Sekunden warten.Nö, Millisekunden.
Schwachsinn! Die Funktion sleep() aus der dos.h kann nur Sekunden. Das steht sogar in der FAQ:
SideWinder, www.c-plusplus.net/forum/39314 schrieb:
Die Funktion sleep() aus der <dos.h> ist nur im Stande ganze Sekunden zu warten.
-
Redest du also wirklich von DOS und nicht von der Windows-Konsole? Welchen Compiler verwendest du dafür und in welcher Version? delay() sollte eigentlich schon der richtige Weg sein...
MfG SideWinder
-
Gin beam schrieb:
Schwachsinn! Die Funktion sleep() aus der dos.h kann nur Sekunden.
Aha, ich meinte das Sleep aus
<windows.h>
.
-
SideWinder schrieb:
Redest du also wirklich von DOS und nicht von der Windows-Konsole?
Ja, echtes DOS.
SideWinder schrieb:
Welchen Compiler verwendest du dafür und in welcher Version?
Turbo C++ 3.0. Aber auch wenn's Visual C++ 1.52c besser macht, hätte ich gerne eine Funktion, die auf allen DOS-Compilern vernünftig funktioniert.
SideWinder schrieb:
delay() sollte eigentlich schon der richtige Weg sein...
Ja, quellcodetechnisch schon. Aber in der Praxis scheint delay wohl folgendermaßen implementiert zu sein:
void delay(unsigned int milliseconds) { clock_t start = clock(); while ((clock() - start) * 1000 / CLOCKS_PER_SEC < milliseconds) ; }
Denn wie ich schon sagte: Man kann den Wert so hoch setzen, wie man will. Die Prozessorauslastung geht immer auf 100 %. Aber unter anderem würde ich zum Beispiel delay(1) gerne benutzen, um in einem Spiel eben die Prozessorauslastung in der Spielschleife zu senken.
Wie ist eigentlich das Windows-Sleep imlementiert? Und wieso kann sleep in DOS nur ganze Sekunden? Gibt es dafür irgendwelche technischen Gründe?
-
Die arbeiten mit RDTSC, d.h. direkt mit einem internen CPU Ticker.
Kannst du mit asm in TC und VC als direkten Opcode verwenden (__emit bzw. db).
-
Da DOS kein "richtiges" Multitasking kann, macht es für einen DOS-Prozess
keinen Sinn die CPU abzugeben. Was soll denn laufen, wenn dein Programm
nicht läuft ?Wenn es darum geht Wärme oder Stromverbrauch zu senken müsste man die CPU runtertakten oder sonstwie in einen Energiesparmodus zu versetzen.
-
merano schrieb:
Da DOS kein "richtiges" Multitasking kann, macht es für einen DOS-Prozess
keinen Sinn die CPU abzugeben. Was soll denn laufen, wenn dein Programm
nicht läuft ?Es geht nicht darum, ob anderen Programmen damit Probleme bereitet werden, sondern darum, dass die Auslastung nicht auf 100 % gehen soll, obwohl eigentlich nur gewartet wird.
merano schrieb:
Wenn es darum geht Wärme oder Stromverbrauch zu senken müsste man die CPU runtertakten oder sonstwie in einen Energiesparmodus zu versetzen.
Das ist doch schon wieder mit Kanonen auf Spatzen geschossen. Es geht mir schlicht und einfach darum, dass ein
delay
nicht 100% Prozessorauslastung haben soll.sleep
hat keine 100%ige Auslastung, kann aber aus irgend einem Grund nur Sekunden.Sleep
hat auch keine 100%ige Auslastung, ist aber für Windows. Wieso sollte jetzt das DOS-Äquivalent zum Windows-Sleep
"CPU runtertakten" sein?
-
Unter Windows verwaltet der Kernel alle Resourcen (wie z.B. CPU) und taktet die CPU runter, schaltet Cores ab u.s.w. wenn die Leistung nicht benötigt werden.
Auch für die Aufteilung der Prozesse auf die Cores ist der Kernel zuständig.Unter DOS muss sich der Programmierer selbst darum kümmern.
Es wäre evtl. möglich einen HLT Befehl aufzurufen und mit einem Timerinterrupt
dann fortzusetzen. Vermutlich nutzt sleep unter DOS diesen Weg.http://en.wikipedia.org/wiki/HLT
http://www.intel.com/design/intarch/manuals/243191.htmHabe noch ein Programm gefunden, das die Powersaving Features der CPU
unter DOS einschalten soll. Wie die CPU unter DOS das nutzen kann wird
nicht erklärt ...
-
Der Quelltext DOSIDLE.ASM ist sehr interessant.
Hier zum Beispiel das warten auf eine TastatureingabeProc int_21h_normalhlt sti ; Enable IRQs for following HLT. mov ah,0bh ; Int 21h FN: "Keypressed?". test [mode_flags],MODE_APM ; APM usage requested? jnz short @@apml ; Yes. @@stdl: hlt ; Enter power saving mode. pushf ; call [dword old_int_21h] ; Simulate int 21h without reentrancy. cmp al,0ffh ; Keystroke ready? jne @@stdl ; No, continue HLTing. jmp short @@done ; Finish.
Wie man sieht wird die CPU mit HLT so lange angehalten, bis ein Tastatur-Interrupt sie aufweckt.
VG
merano