Einschränkung, wieviel % CPU die Python VM bekommt ?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Hallo,

Ich würde gerne einschränken, wieviel % CPU ein Python Programm nutzen darf. Gibt es dafür irgendetwas ?

Evtl. "halbgeheime" Funktionen ?


Danke schonmal für die Antworten.
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Das ist Aufgabe des BS, also auch BS-spezifisch. Welches BS meinst du denn? Das aus Redmond?
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Hallo Joghurt,

mich würde das für beide der grossen OS interessieren,
also Windows und Linux.


Nur warum sollte das aufgabe des OS sein ?
Das verteilt doch nur wer wieviel kriegt, lässt sich aber meines Wissens nicht auf feste idle/last werte festmachen ?

Mir gehts nicht nicht um die prioritäten, sondern darum das das programm wirklich nur 80 % zum beispiel zieht, die cpu demzufolge 20% idle ist ...

Die Java VM kann sowas soweit ich weiss.
Clython
User
Beiträge: 151
Registriert: Samstag 21. August 2004, 13:58
Wohnort: Schweiz, BE-2500

Also in *nix kannst du ja einstellen wieviel Priorität du einem Programm geben willst (mit nice). Das hat weniger mit Python an sich, sondern eher mit der Methode des OS zu tun, wie es die Ressourcen verteilt.
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Die Java VM kann sowas soweit ich weiss.
Wenn die Java VM sowas kann, dann kann sie einstellen wieviel Priorität der Prozess auf der VM bekommt, und wieviel Zeit die VM idlet. Sonst nix, nämlich im besonderen nicht wieviel Prozessorzeit die VM als solches bekommt.

Alles andere ist nämlich Sache des Betriebssystemschedulers, und der kennt unter Unix wie jemand anderes schon sagte nur nice, was einfach schlicht und ergreifend festlegt in welche Priority-Queue der Prozess kommt. Unter Windows kennt er etwas ähnliches, aber ich kenne mich da nicht so ganz genau aus.

Wenn es einen Prozess gibt der laufen kann, so läuft er auch. Das ist bei jedem Multitasking-Betriebssystem so. Da kann die Java-VM noch so viel Verrenkungen machen wie sie will, das einzige wie gesagt was sie machen kann ist zum Beispiel bei 60% Systemauslastung 0.4 Sekunden jede Sekunde zu blockieren, und dem Betriebssystem zu überlassen was es an ihrer Stelle macht. Das ist aber wiederum keine Garantie dass sie wirklich 60% Systemleistung bekommt, denn sobald ein anderer Prozess da ist verringert sich das automatisch.

--- Heiko.
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Guten Morgen :?


Die idee von Modelnine klingt relativ logisch, das die VM einfach sleeps dazugibt. Es ist sicher auch nicht perfekt so, aber zumindest kann ein prozess mit unendlicher benötigter Rechenleistung so die cpu doch nur zu einem bestimmten prozentsatz auslasten.

Das kann wie gesagt unter umständen nützlich sein, auch wenn mittels nice level oder Task_Priority man anderen programmen den vorlauf geben kann.

Übernehmen Threads die Priorität des MainThreads ?
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Antwort auf letzte Frage: unter Unix ja, unter Windows würde ich auch mal denken, aber k.A.

--- Heiko.
BlackJack

Unter Unix und Mac steht übrigens die Funktion `os.nice()` zur Verfügung.
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Kleine letzte Bemerkung: wenn es nur um "Interaktivität" geht, kannst Du auch regelmäßig ein time.sleep(0) einfügen. Das ist im Endeffekt ein Signal, dass wenn in diesem Moment ein anderer Prozess etwas zu tun hat, er es machen darf, und wenn nicht, dann schläft Dein Modul nicht. Sozusagen ein höfliches Angebot den rest seines Time-Slices an den Scheduler zurückzugeben, was der Scheduler aber nur annimmt wenn's auch was zu tun gibt.

--- Heiko.
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Super ModelNine.

Das könnte helfen.

Ist das irgendwo Dokumentiert ?
(und funktioniert das auch überall) ?

Danke :D


Also im WindowsXP scheints nicht zu funktionieren,
trotz das prime95 mitläuft zieht python 2.4 99 % rechenlast.
:-(

Code: Alles auswählen

import time
while True:
    time.sleep(0)


Stimmt es das Python threads keine multi-cpu unterstützen weil das GIL gehalten werden muss - ich als um 2 cpu's auszulasten auch 2 python programme starten muss ?

Ist euch ein thread modul bekannt was erlaubt, threads mittels .sleep und .resume zu steuern ?
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Das könnte helfen.

Ist das irgendwo Dokumentiert ?
(und funktioniert das auch überall) ?
Ich habe den Trick eigentlich von Unix C-Programmierung, da wird er gesondert als (python-äquivalent) select.select([],[],[],0) eingesetzt. Ich hab allerdings auch mal gehört dass es unter Windows tut.

Such mal im Netz nach sleep(0), solltest auf jeden Fall was finden, ich hab heute abend keinen Bock mehr Google zu quälen. ;-)
Stimmt es das Python threads keine multi-cpu unterstützen weil das GIL gehalten werden muss - ich als um 2 cpu's auszulasten auch 2 python programme starten muss ?
Ohne dass ich jetzt genau erkläre warum, ja das stimmt.
Ist euch ein thread modul bekannt was erlaubt, threads mittels .sleep und .resume zu steuern ?
Nein, da nicht plattformunabhängig lösbar. Deswegen gibts auch in der Python STL keine Thread.kill-Funktion, außer für den Haupt-Thread.

Was Du allerdings relativ einfach machen kannst: regelmäßig in der eigentlichen Berechnungsfunktion die Semaphore die Du hälst freigeben, und sie dann wieder acquirieren. Wenn sie nicht aquiriert werden kann (weil zum Beispiel jemand draußen auf die Semaphore wartet), dann unterbricht der laufende Task so lange bis draußen wieder freigegeben ist. Nicht perfekt, aber machbar.

Oder halt Berechnungen in viele kleine, kurze Schritte aufteilen, die Du dann einzeln schedulen kannst.

Im Endeffekt läufts aber immer auf sowas hinaus in Python wenn Du Thread-Stop und -Resume haben willst.

--- Heiko.
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

modelnine hat geschrieben:
Mad-Marty hat geschrieben:Stimmt es das Python threads keine multi-cpu unterstützen weil das GIL gehalten werden muss - ich als um 2 cpu's auszulasten auch 2 python programme starten muss ?
Ohne dass ich jetzt genau erkläre warum, ja das stimmt.
Ok, wie stehen die chancen das das demnächst in irgendeiner Python version behoben sein wird ?

(Ich glaube die chancen sind da sehr gering oder ?)
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Ok, wie stehen die chancen das das demnächst in irgendeiner Python version behoben sein wird ?
Okay, dann gehen wir ein bißchen tiefer in den Interpreter.

Also es stimmt nicht umbedingt dass Python-Programme keine Multi-CPU-Unterstützung haben. Erst mal kurz zum GIL: das GIL ist das sogenannte Global-Interpreter-Lock, ein Thread-Lock das gehalten werden muß damit der Python-Interpreter angesprochen werden kann, der eben nicht reentrant ist. Solange aber in einem Thread keine Python-Bytecodes ausgeführt oder aber andere Dinge die Python-Objekte verändern getan werden muß dieses Lock auch nicht gehalten werden.

In vielen C-Erweiterungen wird das Lock abgegeben wenn möglicherweise ein Betriebssystemaufruf eine gewisse Zeit dauert, und solange ein anderer Python-Thread etwas tun kann, so zum Beispiel im socket-Modul wenn gerade ein socket blockiert weil er auf Daten wartet. Sobald die Rückgabewerte des Systemaufrufs in Python-Objekte verpackt werden muß die GIL wieder gehalten werden.

Dass Python-Threads sich nicht über mehrere CPUs verteilen ist auch falsch; sie tun es schon, nur kann halt eben wenn man sich in Python-Code befindet immer nur eine der CPUs etwas tun, weil das GIL gehalten werden muß.

Wenn Du also eine Aufgabe hast die sich effizient in C kodieren läßt, und die halt eine gewisse Zeit auf jeden Fall braucht (zum Beispiel eine große Primzahl finden), so lässt sich das auch unter Python ohne Probleme parallelisieren indem das GIL von der entsprechenden C-Bibliothek freigegeben wird. Das Betriebssystem wird normalerweise den Thread auf eine andere CPU verschieben wenn diese vorhanden ist.

Dass das GIL verschwindet in der nahen Zukunft: extrem unwahrscheinlich, da es nicht ganz einfach ist einen Interpreter zu schreiben der reentrant ist. Momentan mußt Du Dich also drauf verlassen dass Du entweder eine C-Erweiterung schreibst um das zu tun was Du parallelisieren willst, oder aber mehrere Python-Prozesse starten, die dann über IPC kommunizieren, und jede ihren eigenen Python-Interpreter haben die dann natürlich nicht mehr durch das GIL blockiert werden, da jeder sein eigenes hat.

Letzteres ist auch nicht schwer, vor kurzen wurde in diesem Forum diskutiert wie man mittels subprocess und cPickle Daten zwischen zwei Python-Prozessen austauschen kann.

--- Heiko.
BlackJack

Mad-Marty hat geschrieben:Ok, wie stehen die chancen das das demnächst in irgendeiner Python version behoben sein wird ?

(Ich glaube die chancen sind da sehr gering oder ?)
Jython hat kein GIL. Das macht das was die JVM macht, kann also auch auf mehreren Prozessoren laufen.
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Dazu interessant (ein bißchen detailierter):

http://aspn.activestate.com/ASPN/Mail/M ... ev/2957989

--- Heiko.
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Hi,

so wie ich das lese ist praktisch jeder CPython code thread safe ....

Stimmt das ?

Wenn also 2 threads in die selbe List append, ich mich um keinen Lock o.ä. kümmern brauche - Da ja einer der Threads das GIL hält bis seine op fertig ist und erst dann eventuell abgibt ,,, ?

Und 2te Frage, kann ich erzwingen das ein Python Thread (keine C ext.) ohne GIL auskommt wenn ich mir absolut sicher bin das er nicht auf die selben Daten eines anderen Thread zugreift ?
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

so wie ich das lese ist praktisch jeder CPython code thread safe ....

Stimmt das ?

Wenn also 2 threads in die selbe List append, ich mich um keinen Lock o.ä. kümmern brauche - Da ja einer der Threads das GIL hält bis seine op fertig ist und erst dann eventuell abgibt ,,, ?
Ja und nein. Bei "atomaren" Operationen in Python-Bytecode wie das Anhängen an eine Liste: ja. Bei "nicht atomaren" Operationen (die also aus mehreren Python-Bytecodes bestehen, wie zum Beispiel wenn Du eine eigene Python-Klasse mit überschriebenem __setitem__ hast): nein. Der Python-Interpreter gibt nach einer gewissen Zeit Bytecode interpretieren automatisch die GIL ab (das sind im Normalfall 100 Anweisungen soweit ich weiß), damit auch ein anderer Thread laufen kann.
Und 2te Frage, kann ich erzwingen das ein Python Thread (keine C ext.) ohne GIL auskommt wenn ich mir absolut sicher bin das er nicht auf die selben Daten eines anderen Thread zugreift ?
Nein. Weil das ganze Objekt-Modell (im besonderen der GC) nicht thread-safe ist kannst Du aus nicht mehr als einem Thread gleichzeitig Dinge an Python-Daten (im allgemeinen, nicht im speziellen an den selben Daten) verändern. Das bedeutet dass wenn Du die GIL abgibst, Du auch nicht mehr auf den Python-Interpreter zugreifen _darfst_! Was natürlich auf jeden Fall der Fall ist wenn Du weiterhin Python-Bytecode ausführst.

--- Heiko.
Antworten