Schneller Code vs. Übersichtlichkeit/Wartbarkeit



  • Hallo,

    ich habe folgendes grundlegendes Problem:
    a) Ich möchte in einem Programm große Mengen an Daten verarbeiten.
    b) Das Format in dem die Daten vorliegen ist unterschiedlich.
    c) Der verarbeitende Algorithmus ist prinzipiell für jedes Format gleich, es sind aber einige Konstanten unterschiedlich (z.B. Offsets, wieviele Bits geshiftet werden etc.)

    Mein Ziel ist es jetzt den Code möglichst performant UND übersichtlich zu halten.
    Das gestaltet sich aber recht schwierig.
    Grund: Die Verarbeitung an "einem Stück" ist schnell. Kapselt man nun jetzt gemeinsam genutzte Codeteile bricht die Performance teilweise massiv ein, weil der Compiler dann halt Funktionsaufrufe macht, o.g. Konstanten nicht mehr zur Compilezeit berechnet sondern zur Laufzeit.

    D.h. Ich will ein Stück Code schreiben und den Compiler dazu "überreden" möglichst mehrfach ähnlichen Code zu generieren, weil der schneller ist.
    Bisher ist mir das allerdings nur gelungen, wenn ich das "per Hand" mache. D.h. Code wirklich copy&paste oder per macros. Das ist beides aber extrem hässlich.

    hier mal ein Beispiel:

    void Calculate()
    {
      for(...)
      {
        //some SSE instructions
        for(...)
        {
          //some SSE instructions
          if(condition)
          {
            //some fast SSE instructions
          }
          else
          {
            //even faster SSE instructions
          }
        }
      }
    }
    

    Die if Abfrage in der inneneren Schleife ist völlig ineffizient, weil die Schleifen entsprechend oft durchlaufen werden. Die Bedingung kann sich aber auch während dem Funktionsaufruf nicht ändern.

    Schneller ist dann z.B.:

    if(condition)
    {
      for(...)
      {
        for(...)
        {
          //execute condition code path (slow)
        }
      }
    }
    else
    {
      for(...)
      {
        for(...)
        {
          //execute condition code path (faster)
        }
      }
    }
    

    Da wird die if-Bedingung nach außen gezogen, dafür der for-schleifen code verdoppelt
    Aber wie kann man das elegant lösen?
    Compiliert sind die Algorithmen ca. 20-30 Assembler Instruktionen und jede zusätzliche Instruktion macht das ganze dann halt langsamer.



  • slax schrieb:

    Da wird die if-Bedingung nach außen gezogen, dafür der for-schleifen code verdoppelt

    Kannst du die for-Schleifen nicht in Funktionen auslagern?! 😕



  • Steffo schrieb:

    slax schrieb:

    Da wird die if-Bedingung nach außen gezogen, dafür der for-schleifen code verdoppelt

    Kannst du die for-Schleifen nicht in Funktionen auslagern?! 😕

    Grund: Die Verarbeitung an "einem Stück" ist schnell. Kapselt man nun jetzt gemeinsam genutzte Codeteile bricht die Performance teilweise massiv ein, weil der Compiler dann halt Funktionsaufrufe macht, o.g. Konstanten nicht mehr zur Compilezeit berechnet sondern zur Laufzeit.



  • slax schrieb:

    D.h. Ich will ein Stück Code schreiben und den Compiler dazu "überreden" möglichst mehrfach ähnlichen Code zu generieren[...]

    D.h. du willst Templates!?



  • wenn ich templates nehmen würde. Wie kann ich den Compiler zwingen den gesamten code zu inlinen? Prinzipiell könnte er doch einen Funktionsaufruf daraus machen.



  • Oh nein, du hast den Code für zwei for-Schleifen verdoppelt. Ist doch völlig egal.
    Viel interessanter finde ich, dass der Compiler offensichtlich nicht rafft, dass er das if() nur einmal machen muss..



  • Bei 20-30 instruktionen sollte der compiler jede als inline deklarierte Funktion auch inline machen.

    Ich hoff, du compileirst mit maximalen Optimierungen. In dem Setup sollte der Compiler schon ziemlich gut optimieren.



  • cooky451 schrieb:

    Oh nein, du hast den Code für zwei for-Schleifen verdoppelt. Ist doch völlig egal.
    Viel interessanter finde ich, dass der Compiler offensichtlich nicht rafft, dass er das if() nur einmal machen muss..

    Wie gesagt, die condition kann sich zur Laufzeit ändern (aber nicht während dem Funktionsaufruf). Der VS2008 hats nicht besser optimiert (obwohl er es hätte können).



  • slax schrieb:

    Wie kann ich den Compiler zwingen den gesamten code zu inlinen?

    Das kannst du auch so nicht.

    slax schrieb:

    Wie gesagt, die condition kann sich zur Laufzeit ändern (aber nicht während dem Funktionsaufruf).

    Dann helfen templates natürlich nix.



  • otze schrieb:

    Bei 20-30 instruktionen sollte der compiler jede als inline deklarierte Funktion auch inline machen.

    Ich hoff, du compileirst mit maximalen Optimierungen. In dem Setup sollte der Compiler schon ziemlich gut optimieren.

    Ok, ich sollte noch folgendes erwähnen:
    Die Compilereinstellungen sind auf optimale Geschwindigkeit eingestellt.
    Der Code muss von unterschiedlichen Compilern für verschiedene Plattformen kompiliert werden (x86 u. x64).

    Ja er sollte aber wie kann ich mir sicher sein, ohne jedesmal das Disassembly zu prüfen?



  • slax schrieb:

    Ja er sollte aber wie kann ich mir sicher sein, ohne jedesmal das Disassembly zu prüfen?

    gar nicht...



  • dot schrieb:

    Das kannst du auch so nicht.

    Doch, und zwar indem ich ihn über die hässliche Macromethodik ihn dazu zwinge den kompletten Code aufzublähen. Aber das will ich ja nicht.



  • Gut, Makros sind natürlich ein Weg. Aber ich würd einfach eine inline Funktion verwenden.



  • dot schrieb:

    slax schrieb:

    Wie gesagt, die condition kann sich zur Laufzeit ändern (aber nicht während dem Funktionsaufruf).

    Dann helfen templates natürlich nix.

    Hm.. warum nicht?

    template<bool condition>
    void calc()
    {
      for ()
      {
        for()
        {
          if (condition)
        }
      }
    }
    

    Klar, das ist immer noch nicht erzwungen, aber wenn der Compiler hier immer noch nicht optimiert fress ich nen Donut.



  • Weil condition zur Compiletime bekannt sein muss...

    EDIT: Achso, es geht wirklich nur um ein if. Dann sind Templates natürlich die Lösung...



  • dot schrieb:

    Weil condition zur Compiletime bekannt sein muss...

    Na ja..

    cout << "Wanna condition?";
    bool wanna;
    cin >> wanna;
    if (wanna)
      calc<true>();
    else
      calc<false>();
    


  • Ja, das ist die Lösung. Ich dachte bei Condition gings um irgendwelche Werte die erst irgendwo mitten drin zur Laufzeit bestimmt werden müssten und so...



  • Ahja danke, dass hilft mir ungemein.
    Hatte templates "sorum" bisher noch nicht benutzt.



  • slax schrieb:

    Ahja danke, dass hilft mir ungemein.
    Hatte templates "sorum" bisher noch nicht benutzt.

    ist doch auch humbug...



  • King George schrieb:

    humbug...

    Bitte bleib doch im NadRW Forum, da schätzen wir alle deine Meinung sehr.


Anmelden zum Antworten