Wie erkenne ich ein multi-core / multi-CPU-Maschine zu Prozess-Funktion ruft in einer Schleife parallel?

StackOverflow https://stackoverflow.com/questions/56769

  •  09-06-2019
  •  | 
  •  

Frage

Ich bin derzeit am entwerfen einer Anwendung, einem Modul, das geladen werden große Mengen an Daten aus einer Datenbank und reduzieren es auf einen viel kleineren Satz von verschiedenen Berechnungen, die je nach den Umständen.

Viele der mehr intensiven Operationen Verhalten sich deterministisch und würde sich dafür eignen, um eine parallele Verarbeitung.

Wenn ich eine Schleife iteriert über eine große Anzahl von Daten, die Stücke kommen aus der db und für jeden Aufruf eine deterministische Funktion, ohne Nebenwirkungen, wie würde ich es so machen, dass das Programm nicht warten, bis die Funktion zurück zu kehren, sondern setzt den nächsten Anrufe gehen, so konnten Sie, die parallel verarbeitet werden?Ein naiver Ansatz, um zu demonstrieren, das Prinzip, würde mir für jetzt.

I have read Google ' s MapReduce, Papier, und während ich verwenden könnte, die Allgemeine Prinzip in einer Reihe von Orten, die ich nicht für jetzt, target großen Clustern, sondern es geht um ein einzelnes multi-core-oder multi-CPU-Maschine, die für version 1.0.Also momentan, ich bin mir nicht sicher, ob ich Sie tatsächlich verwenden können die Bibliothek oder würde haben zu Rollen verdummt-down-basic-version selbst.

Ich bin in einem frühen Stadium des design Prozess und so weit bin ich targeting C-etwas (für die Geschwindigkeit entscheidend bit) und Python (für die Produktivität entscheidend bits) als meine Sprachen.Falls zwingende Gründe bestehen, könnte ich wechseln, aber bisher bin ich zufrieden mit meiner Wahl.

Bitte beachten Sie, dass ich bin mir der Tatsache bewusst, dass es möglicherweise länger dauern, um das nächste Stück aus der Datenbank als Prozess der aktuelle und der ganze Prozess wäre dann I/O-gebunden ist.Ich würde allerdings davon ausgehen, für jetzt, dass es Sie nicht und in der Praxis ein db-cluster oder Speicher-Cache oder etwas anderes zu sein, nicht I/O-gebunden ist an diesem Punkt.

War es hilfreich?

Lösung

ich hier etwas werden könnte, fehlt, aber dies scheint recht geradlinig pthreads verwendet wird.

ein kleiner Threadpool mit N Threads in es einrichten und ein Thread steuern sie alle.

Der Master-Thread sitzt einfach in einer Schleife wie etwas zu tun:

  1. Get Datenblock von DB
  2. Finden nächsten freien Thread Wenn kein Thread wartet frei ist dann
  3. Hand über Chunk Worker-Thread
  4. Gehen Sie zurück und nächste Brocken von DB
  5. get

In der Zwischenzeit die Arbeitsthreads sie sitzen und zu tun:

  1. Mark mich als frei
  2. Warten, bis der Mast Thread mir einen Teil der Daten geben
  3. Prozess der Datenblock
  4. Mark mich als wieder frei

Die Methode, mit der Sie diese implementieren können als zwei Mutex gesteuerte Arrays so einfach sein. Man hat die bearbeitete Gewinde in ihr (der Thread) und die anderes angezeigt, wenn jedes entsprechendes Gewinde frei oder besetzt ist.

Tweak N nach Ihren Wünschen ...

Andere Tipps

Nun, wenn .net eine Option ist, sie mit viel Aufwand in gesetzt haben

Wenn Sie immer noch auf Python planen, möchten Sie vielleicht einen Blick haben unter Verarbeitung . Es verwendet Prozesse statt Threads für parallele Rechen (aufgrund der Python GIL) und bietet Klassen für „Workitems“ auf mehrere Prozesse zu verteilen. Mit Hilfe der Pool-Klasse können Sie Code wie folgt schreiben:

import processing

def worker(i):
    return i*i
num_workers = 2
pool = processing.Pool(num_workers)
result = pool.imap(worker, range(100000))

Dies ist eine parallele Version von itertools.imap, die Anrufe über Verfahren verteilt. Sie können auch die apply_async Methoden des Pools nutzen und speichern faul Ergebnisobjekte in einer Liste:

results = []
for i in range(10000):
    results.append(pool.apply_async(worker, i))

Für weitere Referenz finden Sie unter der Dokumentation der Pool-Klasse .

Gotchas:

  • Verarbeitung verwendet fork (), so müssen Sie auf Win32
  • vorsichtig sein
  • Objekte zwischen Prozessen übertragen müssen pickleable sein
  • , wenn die Arbeiter relativ schnell sind, können Sie chunksize zwicken, das heißt die Anzahl der Arbeitseinheiten sendet in einer Charge zu einem Arbeitsprozess
  • processing.Pool verwendet einen Hintergrund-Thread

Sie können den Algorithmus von Google implementieren MapReduce ohne physisch getrennten Maschinen zu müssen. Man denke nur an jedem dieser „Maschinen“ sein „Fäden“. Themen sind auf Multi-Core-Maschinen automatisch verteilt.

Wenn Sie mit einem Compiler arbeiten, die sie unterstützen, würde ich vorschlagen, einen Blick auf http unter: // www .openmp.org für einen Weg, um Ihren Code in einer solchen Art und Weise von Anmerkungen versehen, dass bestimmte Schleifen parallelisiert werden.

Es tut viel mehr als gut, und man kann es sehr hilfreich sein.

Ihre Webseite berichtet, dass gcc4.2 openmp unterstützen, zum Beispiel.

Der gleiche Thread-Pool wird in Java verwendet. Aber die Fäden in threadpools sind serialisable und an anderen Computern und deserialised auszuführen.

Ich habe eine MapReduce-Bibliothek für Multi-Threaded / Multi-Core-Nutzung auf einem einzigen Server entwickelt. Alles wird betreut von der Bibliothek, und der Benutzer hat nur Karte zu implementieren und zu reduzieren. Es wird als Boost-Bibliothek positioniert, aber noch nicht als formalen lib akzeptiert. Schauen Sie sich http://www.craighenderson.co.uk/mapreduce

Sie können bei der Prüfung den Code von libdispatch interessiert sein, die die Open-Source-Implementierung von Apples Grand ist Central Dispatch.

Intel TBB oder boost :: mpi könnte auch für Sie interessant sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top