Wie entwickle ich effektiv parallelisierte Programme?



  • In letzter Zeit beschäftige ich mich mit Dingen, die sehr viel Rechenleistung erfordern und daher unbedingt parallelisiert laufen sollten. Aber den Mehraufwand beim Programmieren bin ich leid und daher lasse nicht selten den Rechner lieber einen Tag länger laufen, falls sich das Problem nicht mit einem simplen #pragma omp parallel for lösen lässt.

    Deswegen suche ich nach Pattern, Klassen, Funktionen oder Herangehensweisen, mit denen ich (nachdem sie einmal implementiert sind) ohne wesentlichen Mehraufwand verschiedene Probleme parallelisieren kann.
    Evtl. auch bestehende Projekte als Beispiel, die guten Gebrauch von mehreren Kernen machen, ohne dass ihr Code dadurch wesentlich länger oder schlechter lesbar geworden wäre.

    Als simples Beispiel könnte man z.B. das hier nehmen:

    auto files=readFileList();
    for (auto&& file : files)
    {
        auto data=readFile(file.path);
        auto result=processData(data);
        processResult(result);
    }
    

    Das soll jetzt parallel laufen und zwar mit einem Thread, der nur readFile() ausführt und 4 (bzw. Anzahl der Kerne) Threads, die processData()/processResult() ausführen.
    Natürlich darf der readFile()-Thread nicht den gesamten Speicher aufbrauchen, falls die anderen Threads nicht hinterherkommen.

    Das auch mit dem Hintergedanken, dass leicht zusätzliche Anforderungen dazu kommen können, z.B.:
    a) processResult() soll nicht im gleichen Thread wie processData() ausgeführt werden, sondern in einem einzigen anderen Thread.
    b) wie a) und zusätzlich soll processResult() in der ursprünglichen Reihenfolge der Datensätze ausgeführt werden (also so wie im Container "files").
    c) es sollen nun X Threads die Daten einlesen, je einer pro physikalischem Datenträger, auf dem die Dateien verteilt sind.

    Wie implementiere ich sowas, dass es kurz, lesbar UND anpassbar (siehe a) bis c)) bleibt?

    Für obiges Problem hatte ich mich mal an einem "Pipeline"-Klassentemplate versucht. Vielleicht war der Ansatz nicht völlig falsch, aber das Ergebnis war jedenfalls unintuitiv/umständlich und ich habe es wieder verworfen.





  • Muss ich mal schauen, ob TBB in Sachen Formalien und Portabilität in Frage kommt.

    Die parallelen Algorithmen sind auf jeden Fall nützlich.

    Die flow graph-Geschichte gefällt mir auf den ersten Blick allerdings nicht. Sieht noch abartiger aus, als was ich sowieso schon hatte, allerdings auch sehr mächtig.
    Liegt vielleicht auch an den bescheuerten Beispielen. Gibt es ein open source-Projekt mit hoher Codequalität, welche diese flow graphs vernünftig einsetzt?



  • Du musst ja auch nicht gleich mit Kanonen auf Spatzen schießen. Vielleicht tuts ja auch eine Pipeline: https://software.intel.com/en-us/node/506068


Log in to reply