Zeitaufwand für Deallokieren von Pointer-Matrizen



  • Hallo alle zusammen,

    ich bastle derzeit an einem Programm, um es schneller zu machen. Und wie ich es "ausmesse", stelle ich fest, daß folgende Zeilen recht viel (um nicht gar zu sagen: VIELZUVIEL) Zeit fressen:

    time=clock();
    for(i=0;i<xSize;i++){ //xSize is dynamic, but 1024 for the measurement
    delete [] inDaten[i]; //jeweils 1024x1024 float-Matrizen
    delete [] inDaten2[i];
    delete [] copy[i];
    }
    delete [] inDaten; delete [] inDaten2; [] delete copy;
    time=clock()-time;
    time/=CLOCKS_PER_SEC;

    Ich habe meine Zeitmessung ebenfalls mit eingefügt. Damit messe ich um die 2 Sekunden, was für die Laufzeit des Programms tödlich ist, da es ohne die (von mir später hinzugefügten) Funktionen, deren Ausschnitt oben steht, 15 Sekunden braucht.

    Ist die Zeit, die zum Deallokieren von Matrizen gebraucht wird IMMER derartig lang? Wenn ja, muß ich meine ganze Programmierung überdenken, denn die Matrizen dienen als temporäre Arrays, die öfter allokiert und geslöscht werden sollen.

    Vielen Dank für eure Antworten bereits im Voraus,

    Baradrist



  • Baradrist schrieb:

    ...

    Du solltest erstmal bei Matrizen auf eindimensionale Arrays umsteigen.



  • Release Mode?



  • Ich weiß nicht, ob new[]/delete[] derartig viel Zeit verbraten, aber falls ja: warum allozierst/deallozierst du denn ständig? Du kannst doch dein Temp-Array einmal allozieren (sofern du eine maximale Größe bestimmen kannst oder diese optimalerweise sogar fest ist) und dann einfach benutzen.



  • Schalte OpenMP im Compiler an und messe es nochmal mit einer parallel for.
    Vorausgestzt du hast ein Mehrkernsystem und halbwegs aktuellen Compiler.

    time=clock(); 
    #pragma omp parallel for
    for(i=0;i<xSize;i++){            //xSize is dynamic, but 1024 for the measurement 
        delete [] inDaten[i];     //jeweils 1024x1024 float-Matrizen
        delete [] inDaten2[i]; 
        delete [] copy[i]; 
    } 
    delete [] inDaten; delete [] inDaten2; [] delete copy; 
    time=clock()-time; 
    time/=CLOCKS_PER_SEC;
    

    Achja wie oben schon erwähnt es ist eher üblich eindimensionale Felder für Matrizen zu benutzen.



  • Vielen Dank für die schnellen Antworten. Da die Matrizen wirklich dynamisch sein müßen (sie sitzen in mehrfach aufgerufenen Hilfsfunktionen denen Pointer-zu-Pointer-Matrizen verschiedener Größe übergeben werden), wird wohl die Variante mit eindimensionalen Matrizen zu Einsatz kommen - was kompliziert wird, da mehrere tausend Zeilen Code durchgegangen sein wollen. Aber es sollte reichen, nur die Temp-Matrizen eindimensional aufzubauen und damit reduziert sich der Aufwand bereits dramatisch =).

    Vielen Dank für den Hinweis!

    Bara



  • Baradrist schrieb:

    Vielen Dank für die schnellen Antworten. Da die Matrizen wirklich dynamisch sein müßen (sie sitzen in mehrfach aufgerufenen Hilfsfunktionen denen Pointer-zu-Pointer-Matrizen verschiedener Größe übergeben werden), wird wohl die Variante mit eindimensionalen Matrizen zu Einsatz kommen - was kompliziert wird, da mehrere tausend Zeilen Code durchgegangen sein wollen. Aber es sollte reichen, nur die Temp-Matrizen eindimensional aufzubauen und damit reduziert sich der Aufwand bereits dramatisch =).

    Vielen Dank für den Hinweis!

    Bara

    Du musst ja nicht direkt alles umschreiben. Messe es mal mit einer OpenMP parallel for schleife durch. Das Ergebnis würde mich interessieren.

    Außerdem solltest du das ganze über Zugriffsfunktionen wie z. B.

    double A (int row, int col)  { return A[col*dim+row]; }
    double Atrans (int row, int col) { return A[row*dim+co]);}
    

    gestalten, dann hält sich die Anzahl der Änderungen in Grenzen



  • Danke für den Hinweis - es wird mir wohl recht viel Arbeit sparen. Leider kann ich OpenMP parallel nicht nehmen, da mein Rechner hier auf Arbeit nur einen Core hat =).

    Bara



  • Baradrist schrieb:

    Danke für den Hinweis - es wird mir wohl recht viel Arbeit sparen. Leider kann ich OpenMP parallel nicht nehmen, da mein Rechner hier auf Arbeit nur einen Core hat =).

    Bara

    Stehen lassen kannst du es trotzdem.
    Wenn der Compiler es nicht kennt wird er es übergehen,
    bei Single Core Systemen wird es auch keine Auswirkungen haben.
    Multicore Systeme müssten eigentlich skalieren.



  • Richtig! Aber ausprobieren was rauskommt kann ich jetzt hier nicht - das meinte ich nur... . 🙂



  • Nochmals: Hast du im Release-Modus kompiliert? Sämtliche Optimierungen ein? Debug-Laufzeitumgebung aus (das ist nicht das gleiche wie Debug-Modus)?



  • Entschuldige, ich hatte deinen Post übersehen.

    Ich habe tatsächlich den Debugger mitlaufen lassen. Ohne angehangenen Debugger (also mit Strg-F5) scheint mein Problem nicht mehr zu existieren... . Danke dir! Was macht der Debugger, daß es mit ihm so lange dauert? Liegt es daran, daß mit ihm nicht optimiert wird?

    Bara



  • Durch den Release Modus aktivierst du in den meisten Entwicklungsumgebungen Optimierungen.

    In Visual Studio ist es glaube ich /O2



  • Baradrist schrieb:

    Was macht der Debugger, daß es mit ihm so lange dauert? Liegt es daran, daß mit ihm nicht optimiert wird?

    Auch, aber nicht nur. Im Debugmodus willst du dir ja auch ggf. Speicherbereiche/Variableninhalte zur Laufzeit anzeigen lassen...



  • Baradrist schrieb:

    Entschuldige, ich hatte deinen Post übersehen.

    Ich habe tatsächlich den Debugger mitlaufen lassen. Ohne angehangenen Debugger (also mit Strg-F5) scheint mein Problem nicht mehr zu existieren... . Danke dir! Was macht der Debugger, daß es mit ihm so lange dauert? Liegt es daran, daß mit ihm nicht optimiert wird?

    Bara

    Das weiß man nicht so genau. Zum einen wird wohl weniger optimiert, zum anderen können ganz andere Funktionen aufgerufen werden als im Release Modus. Gerade bei dynamischer Speicherverwaltung existieren häufig besondere Debug Funktionen, die nicht nur Speicher reservieren, sondern auch noch weitere Kontextinformationen des Aufrufs speichern, um das Auffinden von Speicherlecks zu vereinfachen. Das kostet natürlich jedesmal etwas Zeit, was bei Millionen von Aufrufen zu merkbaren Verzögerungen führen kann.



  • Das weiß man nicht so genau. Zum einen wird wohl weniger optimiert, zum anderen können ganz andere Funktionen aufgerufen werden als im Release Modus.

    Im Debug Modus wird eine andere Heap-Verwaltung genommen. Daher hast Du auch ein anderes Speicher-Layout.


Log in to reply