loop optimieren



  • Nephelauxetic schrieb:

    Das ueberlasse ich dem Compiler. Der compiler optimiert mit den Profiling Informationen und kann also die Loops unrollen wenn er will. Bringen tut das aber nicht viel.

    Ich dachte, Loops unrollen macht er nur wenn er kann - ist aber egal. Ich denke auch, das bringt wirklich nicht viel, 20E6 Takte hört sich nach viel an, ist aber bei einer 1 GHz CPU nur etwa 20 ms. 1 fps, hehe.

    Nephelauxetic schrieb:

    g++ 4.2.3, Linux, -O3 -funroll-loops -fno-gcse

    Man könnte noch folgende Flags ausprobieren:

    -ffast-math -fno-rtti
    

    Ansonsten, ich geb auf 😉 Ich lege großen Wert auf Lesbarkeit und "Debugbarkeit" eines Programms...



  • Ich weiss nicht genau wie die OpenMP Implementierung skaliert. Ich hab mich nur mit MPI beschaeftigt und da waer das nicht trivial zu implementieren. Aber daran gedacht hab ich auch schon

    Aus

    #pragma omp parallel
    {
      #pragma omp for
      for(int i=0; i<n; ++i){
        ...
      }
    }
    

    wird meistens etwas wie:

    #pragma omp parallel
    {
      const int begin = n*omp_get_thread_num() / omp_get_num_threads();
      const int end = n*(omp_get_thread_num()+1) / omp_get_num_threads();
      for(int i=begin; i<end; ++i){
        ...
      }
    }
    

    Skaliert also recht gut mit n wenn die Laufzeit von ... nicht von i abhängt. Bringt aber nur etwas wenn die Anzahl der Cores <<< n

    Ein #pragma parallel for num_threads(2) ist ja schnell vor eine Schleife geschrieben von daher schadet testen wahrscheinlich nicht. Ich glaub aber nicht wirklich dran, dass das bei 2 Cores viel bringt und bei vielen Cores bin ich mir auch nicht sicher.

    Ansonsten sehe ich leider kein Potential mehr in dem Code, sorry.



  • Hast du evtl. ein vollständiges Testprogramm für diese Funktion? Dann könntest du das in Gänze posten (http://rafb.net/paste/ & co.) damit wir eigene Experimente anstellen können. Bloßes Draufschauen hilft bei solchen Microoptimierungen leider oft nicht.



  • OK, ich habe schon ewig nicht mehr mit der gcc rumgespielt, aber wenn ich mich recht entsinne ist es ganz sinnvoll -march zu verwenden.



  • Wenn ihr aus dem Code noch mehr als 10% rausholt, bekommt ihr nen virtuellen Keks.



  • camper schrieb:

    Hast du evtl. ein vollständiges Testprogramm für diese Funktion? Dann könntest du das in Gänze posten (http://rafb.net/paste/ & co.) damit wir eigene Experimente anstellen können. Bloßes Draufschauen hilft bei solchen Microoptimierungen leider oft nicht.

    Ich kann dir den Code per Mail schicken. Das Problem ist das du ganze Bibliothek (fuer Objekte wie topo, conf etc.) einfach riesig ist. Zudem wuerd ich den Code in dieser Form nur ungern ins Netz stellen.

    Helium schrieb:

    aber wenn ich mich recht entsinne ist es ganz sinnvoll -march zu verwenden.

    Ja in der Regel schon. Hier bringt es nichts.

    Ben04 schrieb:

    Skaliert also recht gut mit n wenn die Laufzeit von ... nicht von i abhängt.

    Ausser in den trivialsten Faellen hat man das aber nie.

    LG
    Neph



  • Das hat man sogar erstaunlich oft. Oder war das nur auf dein Programm bezogen?



  • Walli schrieb:

    Das hat man sogar erstaunlich oft. Oder war das nur auf dein Programm bezogen?

    Nein allgemein. Kann sein dass ich aber bis jetzt einfach nur Pech hatte dass ich noch nie eines dieser schoenen Daten-parallelen Lehrbuchbeispiele in der Praxis hatte. 😃

    Aber das ist hier OT.



  • abc.w schrieb:

    -ffast-math -fno-rtti
    

    Das bringt fast 10% auf dem ganzen Programm 🙂 Dies liegt aber am fast-math. no-rtti hat keinen Effekt.



  • Nephelauxetic schrieb:

    Dies liegt aber am fast-math. no-rtti hat keinen Effekt.

    -fno-rtti durfte sich laut gcc manual u.U. auf den Speicherverbrauch auswirken. -ffast-math bewirkt u.a. dass bei Berechnungen keine bedingten Sprungbefehle generiert werden. Damit spart man wahrscheinlich CPU-Takte. Optimal wäre, überhaupt keine Sprünge im Code zu haben, keine Schleifen, keine if-s, keine switches, am besten nur lauter nops 😉 Vielleicht lohnt es sich doch, die verschachtelte Schleife in deiner Funktion irgendwie zu beseitigen. Das ist halt nur problematisch, weil nun ja, Algorithmus umdenken und so was, ist nicht trivial , kompliziert und man muss sich dabei anstrengen 😉 Aber damit hättest Du dann num_solvent_atoms mal was weiss ich wieviele Takte noch mal gespart. Und mit Sicherheit deinen Schein oder Prüfungsnote bekommen.



  • pleevsevsi@farifluset.mailexpire.com

    Die Wirkung der Optimierungsoptionen ist leider recht unzuverlässig, interessant vielleicht auch Acovea

    Evtl bringt es hier etwas, ein wenig mit --param max-reload-search-insns=x herumzuspielen mit großen x (geht wahrscheinlich auf Kosten der Compilierzeit). In der Regel basiert die Suche nach den besten Optionen auf trial&error.



  • Und konnte noch viel aus dem Code rausgeholt werden?



  • by the hammer


Anmelden zum Antworten