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
Sieh dir mal das an: http://pyprocessing.berlios.de/

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()