0

Ich habe meinen Code experimentiert, um "parallele" Befehle an mehrere serielle COM-Ports zu senden.Python Multiprocessing etwas langsamer als Multithreading unter Windows

My Multi-Threading-Code besteht aus:

global q 
q = Queue() 
devices = [0, 1, 2, 3] 
for i in devices: 
    q.put(i) 
cpus=cpu_count() #detect number of cores 
logging.debug("Creating %d threads" % cpus) 
for i in range(cpus): 
    t = Thread(name= 'DeviceThread_'+str(i), target=testFunc1) 
    t.daemon = True 
    t.start() 

und Multi-Processing-Code besteht aus:

devices = [0, 1, 2, 3] 
cpus=cpu_count() #detect number of cores 
pool = Pool(cpus) 
results = pool.map(multi_run_wrapper, devices) 

I zu beobachten, dass die Aufgabe in „Parallel-Serien-Befehle 4 COM-Ports des Sendens "dauert etwa 6 Sekunden und Multi-Processing dauert immer 0,5 bis 1 Sekunde zusätzliche Gesamtlaufzeit.

Irgendwelche Eingaben, warum die Diskrepanz auf einer Windows-Maschine?

+1

Multi-Processing hat immer zusätzlichen Overhead vs. Multi Threading. Multi-Threading verwendet den gleichen Speicherplatz wie der übergeordnete Prozess, während Multi-Processing neuen Speicher für den Prozess zuweisen muss. Es spielen wahrscheinlich mehr Faktoren eine Rolle, aber dieser Overhead ist selbstverständlich. –

Antwort

1

Nun, zum einen vergleichen Sie nicht Äpfel mit Äpfeln. Wenn Sie gleichwertigen Code möchten, verwenden Sie multiprocessing.dummy.Pool in Ihrem Thread-Fall (das ist multiprocessing.Pool implementiert in Bezug auf Threads, nicht Prozesse), so dass Sie mindestens das gleiche grundlegende Parallelisierungsmodell mit verschiedenen internen Implementierungen verwenden, nicht alles ändern auf einmal.

Darüber hinaus hat das Starten der Arbeiter und die Kommunikation von Daten zu ihnen einige Overhead, mehr auf Windows als auf anderen Systemen, da Windows fork neue Prozesse nicht billig hervorbringen kann; es muss eine neue Python-Instanz erzeugen und dann den Status über IPC kopieren, um die Verzweigung zu approximieren.

Abgesehen davon haben Sie nicht genügend Informationen zur Verfügung gestellt; Ihre prozess- und threadbasierten Worker-Funktionen werden nicht bereitgestellt und können zu erheblichen Verhaltensunterschieden führen. Noch haben Sie Informationen darüber zur Verfügung gestellt, wie Sie das Timing durchführen. Wenn jeder Workerprozess die COM-Port-Kommunikationsbibliothek erneut initialisieren muss, kann dies ebenfalls einen nicht-trivialen Overhead zur Folge haben.

+0

Danke für Ihre Eingaben. Die Worker-Funktionen sind für beide Methoden (Multithreading und Multiprocessing) genau gleich, mit Ausnahme der q.put()/q/taskdone() -Aufrufe in Multi-Threading. Und in jeder Thread-Instanz initialisiere ich einen neuen COM-Port, also ist es eigentlich kein Overhead, da ich nicht versuche, denselben COM-Port neu zu initialisieren. Momentan denke ich, dass ich mit Multithreading fortfahre, da es ziemlich stabil für das zu sein scheint, was ich versuche, und auch vergleichsweise schneller. (Verwenden Sie die Start-Stopp-Zeitdifferenz mithilfe der Zeitbibliothek, um sie zu synchronisieren). – eecs

Verwandte Themen