Geschwindigkeit: If-Abfrage in Schleife



  • Wenn ich solchen Code schreibe, habe ich immer ein schlechtes Gewissen:

    const bool cond = ...
    for (...) {
      foo();
      if (cond)
        bar();
      baz();
    }
    

    foo/bar/baz sind dabei in der Regel relativ schnell (wenn auch einige nichttriviale Codezeilen) und die Schleife kann relativ oft durchlaufen werden.

    Kann ich das irgendwie optimieren ohne den Code zu verdoppeln?



  • Ich lehne mich jetzt mal weit aus dem Fenster und behaupte, dass der Compiler das schon optimieren könnte.



  • Naja, meiner (GCC) nicht, der das hier draus:

    goto loop_start:
    loop_end:
      baz();
      if (end_of_loop) goto loop_break;
    loop_start:
      foo();
      if (b) goto loop_end;
      bar();
      baz();
      if (!end_of_loop) goto loop_start;
    loop_break:;
    

  • Mod

    needforspeed schrieb:

    Naja, meiner (GCC) nicht, der das hier draus:

    goto loop_start:
    loop_end:
      baz();
      if (end_of_loop) goto loop_break;
    loop_start:
      foo();
      if (b) goto loop_end;
      bar();
      baz();
      if (!end_of_loop) goto loop_start;
    loop_break:;
    

    Komisch, mein GCC macht daraus nämlich (bei cond = true;)

    loop_start:
    foo();
    bar();
    baz();
    goto loop_start;
    

    Folgerung: Du hast Optimierungen gar nicht eingeschaltet.



  • SeppJ schrieb:

    Komisch, mein GCC macht daraus nämlich (bei cond = true;)

    cond ist nicht eine Compilezeitkonstante, sondern erst zur Laufzeit bekannt und dann auch von Aufruf zu aufruf verschieden. Es ist nur eine Loopinvariante.


  • Mod

    Vollständiger Code, Compilerversion, Kommandozeilenoptionen?
    -funswitch-loops (aktiviert durch -O3) sollte hierfür zuständig sein
    Gut möglich nat. dass der Compiler trotzdem der Meinung ist, dass das Unterlassen dieser Optimierung besser ist.


  • Mod

    needforspeed schrieb:

    SeppJ schrieb:

    Komisch, mein GCC macht daraus nämlich (bei cond = true;)

    cond ist nicht eine Compilezeitkonstante, sondern erst zur Laufzeit bekannt und dann auch von Aufruf zu aufruf verschieden. Es ist nur eine Loopinvariante.

    Dann wird es bei mir (GCC 4.8, O3, x86_64) zu:

    if (cond)
    {
     loop
     {
      foo; bar; baz;
     }
    }
    else
    {
     loop
     {
      foo; baz;
     }
    }
    

    ➡ Das was camper gesagt hat.



  • Nimm halt ein Template.


  • Mod

    zfhrjc schrieb:

    Nimm halt ein Template.

    needforspeed schrieb:

    cond ist nicht eine Compilezeitkonstante, sondern erst zur Laufzeit bekannt und dann auch von Aufruf zu aufruf verschieden. Es ist nur eine Loopinvariante.


Anmelden zum Antworten