Schon wieder Microoptimierung???? [xor oder assign? index oder pointer?]



  • Hallo,
    ich schreibe gerade eine Klasse für sehr große Zahlen. Dafür muss ich lange arrays aus size_t auf 0 setzten. Welche Variante sollte ich verwenden?

    for(size_t i = 0;i!=array_ende;++i)
    {
        array[i] = 0;
        array[i] ^= array[i];
    }
    for(size_t * p = anfang; p!=ende; ++p)
    {
       *p = 0;
       *p ^= *p;
    }
    

    Gibt xor mit sich selbst Performance Vorteile gegenüber assign mit null? Sollte man index operatoren zum Zugriff auf arrayelemente benutzen oder zeiger? Und ja, es geht hier um zeitkritische Bereiche in meinem Programm 🙂



  • allgemein sind indexzugriffe besser, weil sie die tendenz haben mit umliegendem code den druck auf die register zu senken. der a^=a-Trick bringt nur was bei registern. hier liest du erst aus dem ram, rechnest was und schreibst dann, statt nur zu schreiben.
    aber das alles ist völlig irrelevant. die normalste füllschleife erkennt dein compiler am ehesten, denkt sich sein memset und haut optimalen code raus.



  • volkard schrieb:

    die normalste füllschleife erkennt dein compiler am ehesten, denkt sich sein memset und haut optimalen code raus.

    In dem Fall darf man doch durchaus auch selbst auf memset zurückgreifen wenn man dem Compiler das "Erraten" nicht zutraut - bzw. erzeugten Code unter voller Optimierung vergleichen und die beste Variante auswählen.

    memset(array, 0, array_ende*sizeof(array[0]));
    memset(p, 0, (ende-anfang)*sizeof(*p));
    

    Oder nicht?



  • pumuckl schrieb:

    Oder nicht?

    Meine Begründungen und Alastairs Trieb führen zwangsläufig zu pumuckls Vorgehen.



  • Oder du benutzt std::fill, da erkennt der Compiler automatisch den Typ und die Grösse des zu füllenden Bereichs. Wenn die STL auch noch schlau ist und PODs erkennt wird sie ebenfalls ein memset benutzen.



  • @Alastair:
    du hast mächtig einen an der klatsche.
    schreib das was du machen willst. wenn du was auf null setzen willst, schreib "= 0".
    der compiler wird schon wissen was schneller ist, XOR oder MOV.



  • Nachdem meine Fragen hier so gut ankamen, habe ich gleich noch eine:
    welche Schreibweise würdet ihr bevorzugen?

    const unsigned int flip = ~0;
    
    void flip_bits(unsigned int arr[])
    {
       for(unsigned int i=0;i!=array_groesse;++i)
          arr[i]=~arr[i];
          //oder
          arr^=flip;
    }
    

    Bei der zweiten Methode würde man zumindest eine temporäre Variable sparen...



  • edit: es muss natürlich arr[i]^=flip heißen.



  • Hier stand Mist.

    MfG SideWinder



  • die frage kannst du dir selbst beantworten.

    übersetz die anweisung die da steht einfach mal auf deutsch. beide varianten.
    das, was dann weniger kompliziert klingt, ist auch die bessere variante code zu schreiben. wenn nicht meistens, dann zumindest in diesem fall.



  • Also werden beide Varianten in den exakt gleichen Maschinencode optimiert?


  • Mod

    Alastair schrieb:

    Also werden beide Varianten in den exakt gleichen Maschinencode optimiert?

    Das musste selber prüfen, wir kennen ja schließlich deinen Compiler nicht. Aber wahrscheinlich ja. Genauso wie das meiste andere vermeintliche Mikrooptimierungszeug.



  • SeppJ schrieb:

    Alastair schrieb:

    Also werden beide Varianten in den exakt gleichen Maschinencode optimiert?

    Das musste selber prüfen,

    Und zwar auf jeder Zielplattform (OS, CPU,...) und mit jedem Zielcompiler. Viel Spaß bei den #ifdef's.


Anmelden zum Antworten