Seite 1 von 1
multicore cpus nutzen
Verfasst: Montag 9. Juni 2008, 22:11
von bigpappa
Hallo,
ich habe ein recht rechenintensives programm geschrieben. Nun ist mir aufgefallen das auf multicore plattformen trotz threading nur eine CPU genutzt wird.
Ich habe die berechnung in 4 threads aufgeteilt die ich folgendermaßen aufrufe:
Code: Alles auswählen
th1 = threading.Thread(target=self.GetPath, args=(0, calls))
th1.start()
Wie müßte ich das threading implementieren um tatsächlich die performance auszuschöpfen?
Vielen Dank.
Verfasst: Montag 9. Juni 2008, 22:12
von veers
Verfasst: Montag 9. Juni 2008, 22:26
von BlackJack
Alternativ vielleicht auch:
http://www.parallelpython.com/
Und Pyro ist auch einen Blick wert.
Verfasst: Dienstag 10. Juni 2008, 09:01
von bigpappa
ich hab mir parallelpython angeschaut, ich denke das sollte meinen zwecken dienlich sein.
nun möchte ich das allerdings innerhalb einer klasse nutzen.
Code: Alles auswählen
class CreateImportFiles():
############################################################################
# Init
############################################################################
def __init__(self, parent,
argKonfiguration
):
self.MainApp = parent
self.Konfiguration = argKonfiguration
self.DebugLevel = 12
self.IOPoints = []
self.FreelanceExportPvLst = []
def CreatePathListAll(self):
job_server=pp.Server()
calls=len(self.IOPoints) / 2
job_server.submit((self.WritePath), (self, 0, calls))
job_server.submit((self.WritePath), (self, calls, len(self.IOPoints)))
job_server.wait()
def WritePath(self, Start, End):
for k in range(Start, End):
if self.IOPoints[k][0] == self.FreelanceExportPvLst[0] :
#hier wird berechnet und einträge in self.IOPoints hinzugefügt und entfernt.
Dabei bekomme ich den Fehler 'TypeError : the sip.wrapper type cannot be instantiated or sub-classed'.
Funktioniert das überhaupt innerhalb einer Klasse? Oder muss ich WritePath in eine eigene Klasse packen? Kann parallelpython innerhalb einer Klasse genutzt werden?
Vielen dank
Verfasst: Dienstag 10. Juni 2008, 09:29
von BlackJack
Wo genau tritt denn der Fehler auf? Kompletter Traceback wäre nicht schlecht.
Grundsätzlich sollte es egal sein von wo man das benutzt.
Vielleicht kannst Du das Beispiel auch soweit reduzieren, dass es möglichst klein aber vollständig ist und immer noch das Problem aufweist.
`CreateImportFiles` ist übrigens ein ungünstiger Name für eine Klasse. Insbesondere wenn man Funktionen nach dem gleichen Muster benennt.
Verfasst: Dienstag 10. Juni 2008, 10:39
von bigpappa
hallo,
hier eine nachbildung in der python idle,
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
##general import
import pp
class ImportFiles():
def __init__(self, parent,
argKonfiguration
):
self.MainApp = parent
self.DebugLevel=12
self.Konfiguration = argKonfiguration
self.PvLst = []
self.IOLst = []
def create_path_list(self):
job_server = pp.Server()
job_server.submit((self.write_path), (self, 0, len(self.IOLst)))
job_server.wait()
def write_path(self, start, end):
print 'writepath'
for k in range(start, end):
for Pv in self.PvLst:
if Pv[0] == self.IOLst[k][0]:
print 'extend IO: ' + self.IOLst[k][0]
self.IOLst[k].append(Pv[1])
############################################################################
# Local call for testing
############################################################################
if __name__ == "__main__":
print 'start tc'
konfig=[12,1,2]
importedfiles=ImportFiles('none', konfig)
importedfiles.IOLst = [['IO-Name1','Typ','DescLong', 'DescShort'],
['IO-Name2','Typ','DescLong', 'DescShort'],
['IO-Name3','Typ','DescLong', 'DescShort'],
['IO-Name4','Typ','DescLong', 'DescShort']]
importedfiles.PvLst = [['IO-Name1', 'Parameter1', 'Parameter2'],
['IO-Name2', 'Parameter1', 'Parameter2'],
['IO-Name3', 'Parameter1', 'Parameter2'],
['IO-Name4', 'Parameter1', 'Parameter2'],
['IO-Name5', 'Parameter1', 'Parameter2']]
print 'start create_path_list'
importedfiles.create_path_list()
print importedfiles.IOLst
print 'done tc'
und der traceback dazu:
Code: Alles auswählen
start tc
start create_path_list
Traceback (most recent call last):
File "C:\Grillo\parallelpython.py", line 49, in <module>
importedfiles.create_path_list()
File "C:\Grillo\parallelpython.py", line 20, in create_path_list
job_server.submit((self.write_path), (self, 0, len(self.IOLst)))
File "C:\Python25\Lib\site-packages\pp.py", line 395, in submit
sfunc = self.__dumpsfunc((func,)+depfuncs, modules)
File "C:\Python25\Lib\site-packages\pp.py", line 582, in __dumpsfunc
sources = [self.__get_source(func) for func in funcs]
File "C:\Python25\Lib\site-packages\pp.py", line 660, in __get_source
sourcelines = inspect.getsourcelines(func)[0]
File "C:\Python25\lib\inspect.py", line 618, in getsourcelines
lines, lnum = findsource(object)
File "C:\Python25\lib\inspect.py", line 494, in findsource
raise IOError('could not find class definition')
IOError: could not find class definition
Verfasst: Dienstag 10. Juni 2008, 11:14
von BlackJack
Das ist jetzt aber eine andere Fehlermeldung. Und bei mir läuft das Programm problemlos durch.
Kannst Du das mal ohne IDLE probieren?
Verfasst: Dienstag 10. Juni 2008, 11:58
von bigpappa
stimmt, die erste fehlermeldung erhalte ich in eric, da ist der ablauf aber auch komplexer.
ohne idle läuft der test ohne fehlermeldung durch, aber er tut dennoch nicht was ich erwarte.
in write_path sollte self.IOLst eigentlich erweitert werden, und die print anweisungen erhalte ich auch nicht auf der Konsole.
Verfasst: Dienstag 10. Juni 2008, 13:22
von BlackJack
Du führst die Jobs, bzw. den Job ja gar nicht aus. Die `submit()`-Methode liefert ein aufrufbares Objekt, dessen *Aufruf* asynchron ist!
Code: Alles auswählen
def create_path_list(self):
job_server = pp.Server()
half_length = len(self.IOLst) // 2
job1 = job_server.submit(self.write_path, (0, half_length))
job2 = job_server.submit(self.write_path,
(half_length, len(self.IOLst)))
job1()
job2()
Allerdings befreit auch `pp` nicht von den üblichen Problemen die beim Verändern von gemeinsamen Datenstrukturen auftreten. Man sollte die parallel ausgeführten Funktionen besser so schreiben, dass sie ein Ergebnis liefern, dass Du dann am Ende zusammen führst. Beispielsweise so:
Code: Alles auswählen
def create_path_list(self):
job_server = pp.Server()
half_length = len(self.IOLst) // 2
job1 = job_server.submit(self.write_path, (0, half_length))
job2 = job_server.submit(self.write_path,
(half_length, len(self.IOLst)))
self.IOLst = job1() + job2()