Python Numpy und Quad Core (Multi-Processing)

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
Benutzeravatar
wollmich
User
Beiträge: 9
Registriert: Montag 11. Februar 2008, 16:31
Wohnort: Bern (CH)

Für umfangreiche Berechnungen brauche ich Python 2.5.1 und Numpy 1.0.4 unter Windows XP. Mit py2exe kann ich problemlos eine Anwendung (Randbemerkung: ich brauche wx für die Oberfläche) erzeugen.

Nun meine Fragen:
Numpy braucht immer nur einen Prozessor meines Quad Cores (nicht multithreading oder multiprocessing fähig). Ist das richtig?

Programmiere ich in Python mit von treading.Thread abgeleiteten Klassen braucht Python immer noch nur einen Prozessor. Das hat scheinbar irgendetwas mit GIL zutun?!? Verstehe ich nicht ganz.

Verwende ich Parallel Python kann ich mein Problem schön in Jobs aufteilen und meine Quad Core wird voll ausgereizt. Sobald ich aber Parallel Python brauche funktioniert das mit py2exe erstellte File nicht mehr. Gibt schon ein Problem bei der Zeile job_server = pp.Server().
Hat hier irgendwer Erfahrung mit Parallel Python und py2exe?

Mit freundlichen Grüssen Wollmich
Zuletzt geändert von wollmich am Mittwoch 13. Februar 2008, 10:14, insgesamt 1-mal geändert.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi,

Willkommen im Forum!

Das ist vielleicht nicht eine direkte Antwort auf Deine Frage, aber womöglich hilft Dir folgender Wikieintrag weiter: http://www.scipy.org/Cookbook/Multithreading (Die Attachments sind in der linken Spalte.)

Wenn das bei Dir funktioniert, könntest Du ggf. auf parallel python verzichten. Hängt natürlich von der Art Deiner Berechnungen ab.

Gruß,
Christian

PS Fange auch gerade erst an Threading zur parallelisierung in numpy zu nutzen.
Benutzeravatar
wollmich
User
Beiträge: 9
Registriert: Montag 11. Februar 2008, 16:31
Wohnort: Bern (CH)

Vielen Dank, kannte die Seite bereits, aber die Anhänge hätte ich wohl nie gefunden :wink:

Kleine stupides Beispiel:

Code: Alles auswählen

import numpy

def f(x):
    a = numpy.linalg.inv(numpy.identity(1000))
    print 'inside f %d' %x

foreach(f, range(24))
belastet meinen Quad Core nur 25% Prozent (TaskManager).

Mit Parallel Python läuft das ganze ca. viermal so schnell.

Hat irgendwer Erfahrungen mit MPI?
Was ist mit der Mpi4Py Seite auf scipy.org los?
Bin für jeden Hinweis dankbar.[/code]
Zuletzt geändert von wollmich am Mittwoch 13. Februar 2008, 10:10, insgesamt 3-mal geändert.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

wollmich hat geschrieben: Was ist mit der Mpi4Py Seite auf scipy.org los?
Gar nichts ;-). Das Problem ist, daß scipy.org auf einem entought-Server liegt. Das ist ja auch sehr nett von entought, aber leider ist der Server völlig überlastet, weil man nicht mit so hohen Zugriffzahlen gerechnet hat. Man will das Problem bald lösen - aber das hilft Dir jetzt nichts. Was hilft ist u. U. einfach Geduld.

Das mit dem "viermal so schnell" gibt mir zu denken. Da habe ich jetzt zwar auch keine Erklärung für, tut mir aber leid, Dich erst auf den falschen Pfad geführt zu haben.
Jetzt kann ich Dir leider nicht mehr weiterhelfen: Wie gesagt, da bin ich auch nur Anfänger. Wenn Dir hier niemand weiterhelfen kann, frage doch mal auf der scipy-Mailingliste nach den Erfahrungen der Leute.

Gruß,
Christian
Benutzeravatar
wollmich
User
Beiträge: 9
Registriert: Montag 11. Februar 2008, 16:31
Wohnort: Bern (CH)

Habe inzwischen ein paar Internetseiten zum Thema gefunden:
http://wiki.python.org/moin/ParallelProcessing
http://pyprocessing.berlios.de

Auf der pyprocessing Seite hat es sogar einen Hinweis bezüglich py2exe

Ich habe das mal ausprobiert und es funktioniert fürs erste nicht mal schlecht:

Beispiel mit pyprocessing:

Code: Alles auswählen

# Test pyprocessing - wollmich 12.02.2008

import processing
import numpy
import time

def f(x):
    """stupid dummy function"""
    a = numpy.linalg.inv(numpy.identity(1000))
    #print 'inside f %d' %x
    return 'f %d' %x

def test(np, n):
    if np == 0:
        _t0 = time.time()
        res = map(f, xrange(n))
        _t1 = time.time()
    else:
        pool = processing.Pool(processes=np)
        _t0 = time.time()
        res = pool.map(f, xrange(n))
        _t1 = time.time()
    t = _t1 - _t0
    return t,res

if __name__ == '__main__':
    processing.freezeSupport()
    n = 24
    t0 = 0
    t1 = 0
    for np in range(0,processing.cpuCount()+1,1):
        t, res = test(np,n)
        if np == 0: t0 = t
        if np == 1: t1 = t
        print 'Processes: %d, Time: %7.3f, Ratio A: %.3f, Ratio B: %.3f'\
        %(np, t, t0/t, t1/t)
        #print res
Output (CMD Line):

Code: Alles auswählen

D:\Multi-Processing\pyprocessing>test_pyprocessing.py
Processes: 0, Time:  21.954, Ratio A: 1.000, Ratio B: 0.000
Processes: 1, Time:  22.423, Ratio A: 0.979, Ratio B: 1.000
Processes: 2, Time:  11.578, Ratio A: 1.896, Ratio B: 1.937
Processes: 3, Time:   8.172, Ratio A: 2.686, Ratio B: 2.744
Processes: 4, Time:   6.563, Ratio A: 3.345, Ratio B: 3.417

D:\Multi-Processing\pyprocessing\dist>test_pyprocessing.exe
Processes: 0, Time:  18.610, Ratio A: 1.000, Ratio B: 0.000
Processes: 1, Time:  18.782, Ratio A: 0.991, Ratio B: 1.000
Processes: 2, Time:   9.750, Ratio A: 1.909, Ratio B: 1.926
Processes: 3, Time:   6.954, Ratio A: 2.676, Ratio B: 2.701
Processes: 4, Time:   5.625, Ratio A: 3.308, Ratio B: 3.339
Also man sieht das mit dem "viermal so schnell" stimmt nicht ganz. :?
Mit 4 Prozessen ist man nur ca. 3.4 mal so schnell als mit einem einzigen. Dies hat mit Intels Aufbau des Quads zu tun (immer zwei Cores teilen sich einen L2-Cache). Man sieht auch, dass man mit 2 Prozessen ca. 1.9 mal so schnell ist. Mit Quads von AMD, die einen anderen Aufbau haben, könnte man ca. 3.9 mal so schnell sein.

Wieso das exe schneller läuft, ist mir unklar?

Werde morgen noch das gleiche Beispiel mit Parallel Python machen.
Zuletzt geändert von wollmich am Mittwoch 13. Februar 2008, 10:24, insgesamt 1-mal geändert.
Benutzeravatar
wollmich
User
Beiträge: 9
Registriert: Montag 11. Februar 2008, 16:31
Wohnort: Bern (CH)

Und das ganze noch mit Parallel Python:

Code: Alles auswählen

# Test Parallel Python - wollmich 13.02.2008

import pp
import numpy
import time

def f(x):
    """stupid dummy function"""
    a = numpy.linalg.inv(numpy.identity(1000))
    #print 'inside f %d' %x
    return 'f %d' %x

def test(np, n):
    if np == 0:
        _t0 = time.time()
        res = map(f, xrange(n))
        _t1 = time.time()
    else:
        job_server = pp.Server(ncpus=np)
        jobs = []
        _t0 = time.time()
        for i in xrange(n):
            jobs.append(job_server.submit(f,(i,),(),('numpy',)))
        res = [job() for job in jobs]
        _t1 = time.time()
    t = _t1 - _t0
    return t,res

if __name__ == '__main__':
    n = 24
    t0 = 0
    t1 = 0
    for np in range(0,4+1,1):
        t, res = test(np,n)
        if np == 0: t0 = t
        if np == 1: t1 = t
        print 'Processes: %d, Time: %7.3f, Ratio A: %.3f, Ratio B: %.3f'\
        %(np, t, t0/t, t1/t)
        #print res
Output (Python Scripter - Python Engine Remote):

Code: Alles auswählen

Processes: 0, Time:  18.625, Ratio A: 1.000, Ratio B: 0.000
Processes: 1, Time:  22.235, Ratio A: 0.838, Ratio B: 1.000
Processes: 2, Time:  11.437, Ratio A: 1.628, Ratio B: 1.944
Processes: 3, Time:   8.079, Ratio A: 2.305, Ratio B: 2.752
Processes: 4, Time:   6.453, Ratio A: 2.886, Ratio B: 3.446
Output (CMD Line):

Code: Alles auswählen

D:\Multi-Processing\pp>test_pp.py
Processes: 0, Time:  21.970, Ratio A: 1.000, Ratio B: 0.000
Processes: 1, Time:  21.829, Ratio A: 1.006, Ratio B: 1.000
Processes: 2, Time:  11.297, Ratio A: 1.945, Ratio B: 1.932
Processes: 3, Time:   7.922, Ratio A: 2.773, Ratio B: 2.755
Processes: 4, Time:   6.375, Ratio A: 3.446, Ratio B: 3.424
Mit py2exe kann ich zwar ein EXE erstellen, aber es funktioniert nicht :(

Parallel Python hat ein paar Vorteile gegenüber pyprocessing. Siehe dazu die Webseite: http://www.parallelpython.com

Hat jemand mehr Erfahrung auf dem Gebiet. Bin wirklich für jeden Hinweis sehr dankbar.
Antworten