Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Parallele Abarbeitung einer for schleife



  • Hallo zusammen,

    Ich arbeite an einer Anwendung in der ich ein dreidimensionales array 7x7x7 an Objekten aus einer selbst gebauten Klasse habe. In der Klasse habe ich eine clear() - Funktion eingebaut, mit der ich sämtliche Werte eines Objekts dieser Klasse zurücksetzen kann (alle strings="", int=0 usw).
    Weiterhin habe ich eine Funktion gebaut, in der ich alle im array befindlichen Objekte zurücksetzen kann. Diese Funktion besteht im wesentlichen aus 3 for-schleifen:

    clearall(){
    
    for(int i=0; i<7; i++){
    for(int j=0; j<7; j++){
    for(int k=0; k<7; k++){
        Arrayname[i][j][k].clear();
    }}}
    
    }
    

    Das Problem ist, dass der gesamte Durchlauf relative lange ist. Ich habe mich gefragt, ob es irgendwie möglich ist, die einzelnen Objekte des Arrays parallel abzuarbeiten. Da sie unabhängig voneinander sind, sollte das gehen. Nach der for-verschachtelung soll es natürlich erst weitergehen, wenn alle "clear()" durchgeführt wurden.
    Ich bin nach längerer Recherche auf die Klassen QThread und QtConcurrent gestoßen. Leider bin ich mit dieser Doku etwas überfordert und einfache Beispiele, die ich auf meinen Fall übertragen kann, finde ich nicht. Ich schätze, QtConcurrrent ist das richtige für mich, allerdings gibt es dort auch gefühlt 1000 verschiedene Funktionen. Kann mir jemand sagen, was das Richtige für mein Problem ist und wie es ie Funktion anwenden kann?

    Vielen Dank!



  • Es is einfacher, OpenMP to benutzen.
    777 Array ist nicht arg viel. I glaube nicht, es lohnt sich, so was an einer GUI Anwendung zu beschleunigen.



  • Danke, habe mich gerade bzgl. OpenMP informiert. Scheint das zu sein, was ich brauchen könnte.
    Funktioniert das mit jedem Compiler? Auch mit dem mingw? Dazu konnte ich noch nichts finden.


  • Lifetime Qt Champion

    Hi
    ist Arrayname ein normales c-Array, so dass Sie wie folgt vorgehen könnten

     ArrayDef Arrayname[7][7][7];
     ArrayDef *ptr =  &Arrayname[0][0][0];
    
       for (int cc=0; cc < 7*7*7 ; cc++ ) {
        ptr->clear();
        ptr++;
       }
    
    

    Aber für eine 7x7x7 Schleife scheint es nicht nötig zu sein, da sie sehr schnell sein sollte?



  • @Freakonaleash OpenMP ist verfuegbar and gratis auf WIndows und Linux
    https://www.dartmouth.edu/~rc/classes/intro_openmp/compile_run.html



  • @JoeCFD danke! Werde ich mal testen.

    @mrjj : interessanter Ansatz. Hätte nicht gedacht, dass es dadurch schneller wird. Bzgl "7x7x7 ist nicht so viel": die clear() - Funktion habe ich selbst implementiert. Dort werden viele strings auf "" gesetzt und sogar nochmal schleifen durchlaufen. Ich denke, es "summiert" sich dadurch....


  • Lifetime Qt Champion

    @Freakonaleash
    Hi
    Normalerweise kann das Abrollen von Schleifen die Geschwindigkeit erhöhen, aber
    ich bin mir in diesem Fall nicht sicher.
    Es könnte sein, dass das eigentliche reset() der zeitaufwändigste Teil ist, wie Sie sagen.


  • Lifetime Qt Champion

    @Freakonaleash said in Parallele Abarbeitung einer for schleife:

    Dort werden viele strings auf "" gesetzt und sogar nochmal schleifen durchlaufen.

    Dann bringt es wenig diese 3 Schleifen zu optimieren, da die Anzahl der clear() Aufrufe gleich bleibt und dort die meiste Arbeit stattfindet. Bei sehr großen Arrays könnte man mit dem Ansatz von @mrjj die Arbeit auf mehrere Threads verteilen solange kein UI betroffen ist.



  • @jsulm Bei sehr großen Arrays könnte man mit dem Ansatz von @mrjj die Arbeit auf mehrere Threads verteilen solange kein UI betroffen ist.
    nicht moeglich wegen ptr++;


  • Lifetime Qt Champion

    @JoeCFD Sicher ist es möglich. Warum sollte das nicht möglich sein? Pointer können auch wie Arrays benutzt werden: ptr[index]. Einfach für jeden thread einen bereich des Array definieren: begin/end und dann in diesem Bereich iterieren:

    void doWork(int begin, int end, ArrayDef *ptr)
    {
        for (int cc=begin; cc < end ; cc++ ) {
            ptr[cc].clear();
           }
    }
    

Log in to reply