[Performancefrage]



  • Wann macht es Sinn in einem Programm aus Performancegruenden ein Vielfaches, bzw. ein Bruchteil der Word Size(z.B. 32Bit) zu nehmen?

    Also z.B. bei den build-in-types ist es ja sowieso schon immer ein Bruchteil/Vielfaches der Word Size.z.B. int=Word Size

    Aber macht es Sinn anstatt von[cpp]char array[31][/cpp]

    char array[32]
    

    zu nehmen?

    Oder statt[cpp]for(int i=1;i<=25;++i)[/cpp]

    for(int i=1;i<=32;++i)
    

    ,
    edit:muss natuerlich 1 sein
    ....

    ....

    Mir faellt auf, das oft in Code als Arraysize/Laufvariable/Konstante 32,128,512 genommen wird.
    thx in advance



  • Bei deinen Beispielen imho nicht.



  • Die Arrayschleifen aufzurunden bringt schonmal gar nix, da ja trozdem der Zugriff Byteweise erfolgt (bei Char).

    Und zum Speichern in Strukturen biegt das jeder moderne Compiler an 4 Byte grenzen.
    Es sei denn, es ist ihm explizit anders geboten, dann mögen Füllbytes Sinn haben.

    for(int i=0;i<=32;++i)

    Ist übrigens Falsch, da hier 33 Elemente durchlaufen werden.



  • Aber jetzt bitte nicht nur IMHO, sondern bitte mit einer mathematischen Begruendung.



  • Raptor schrieb:

    Aber jetzt bitte nicht nur IMHO, sondern bitte mit einer mathematischen Begruendung.

    In einem gutem Buch über Optimierung stand mal eine Leitregel:

    Assume nothing!

    Sprich: Wenn es not tut, schnapp dir deine Stoppuhr und teste es konkret aus.



  • Hallo.

    Also es bringt absolut nichts z.B. in einer Schleife, die laut (vorher überlegtem) Algorithmus bis 25 laufen soll, einfach auf 32 zu setzen; eher im Gegenteil.

    _Aber_ wenn Du die freie Wahl hast, sind Zweierpotenzen (z.B.25=322^5=32) schon sinnvoll. Ein Beispiel:

    Du möchtest ein Bild bearbeiten, dass Du beispielsweise von einem Framegrabber geliefert bekommst. Sagen wir mal Graubild (256 Farben). Das Bild wird als 1 D-unsigned Char Array gespeichert (die Zeilen).
    Jetzt hast Du die freie Wahl wie groß, Dein Bild sein soll. Und hier solltest Du dann als Arraygröße eine Zweierpotenz(z.b. 512x512) nehmen.
    Weil:
    Da das Bild zeilenweise gespeichert ist, musst Du auf eine einzelnes Pixel an der Position (x,y) im Bild mit x+y*Bildbreite zugreifen. Hast Du jetzt eine Zweierpotenz als Bildbreite gewählt, wird die Multiplikation automatisch durch ein ShiftLeft ersetzt.

    Auf einem Pentium 4 hat eine Integermultiplikation eine Latenz von 14-18 Takten und einen Durchsatz von 5 Takten. Der Shift nur 4 Takte Latenz, 1 Takt Durchsatz.
    Na gut, bei _einem_ Bild bringt das nicht sehr viel. Aber nehmen wir an, Du verarbeitest 500 Bilder/s, sagen wir mal 256x256 Pixel/Bild; dann sind das schon 32 Millionen Multiplikationen pro Sekunde.....

    Wenn Du Divisionen verwendest, kann ich Dir sogar dringend empfehlen Dir einen Algorithmus auszudenken, der nur durch Zweierpotenzen dividiert.

    Ausserdem ist nicht nur die Arraygröße wichtig, sondern auch der _Anfang_ des Arrays im Speicher. Der P4 liest aus dem Hauptspeicher immer in 64 Byte Blöcken(Cachelines), 'WordSize' ist da eher unwichtig. Aber dazu ggf. mehr auf Anfrage.. 😉

    Und wichtig, erst den zugrundeliegenden Algorithmus optimieren!

    Gruß



  • SeppSchrot schrieb:

    Die Arrayschleifen aufzurunden bringt schonmal gar nix, da ja trozdem der Zugriff Byteweise erfolgt (bei Char).

    Und zum Speichern in Strukturen biegt das jeder moderne Compiler an 4 Byte grenzen.
    Es sei denn, es ist ihm explizit anders geboten, dann mögen Füllbytes Sinn haben.

    for(int i=0;i<=32;++i)

    Ist übrigens Falsch, da hier 33 Elemente durchlaufen werden.

    Es werden nur 32 Elemente durchlaufen, da beim ersten Mal die 0 zur 1 wird.
    Naja, das ++i würd ich in ner Schleife auch nicht machen, aber das ist eh Geschmackfrage..



  • DocJunioR schrieb:

    SeppSchrot schrieb:

    Die Arrayschleifen aufzurunden bringt schonmal gar nix, da ja trozdem der Zugriff Byteweise erfolgt (bei Char).

    Und zum Speichern in Strukturen biegt das jeder moderne Compiler an 4 Byte grenzen.
    Es sei denn, es ist ihm explizit anders geboten, dann mögen Füllbytes Sinn haben.

    for(int i=0;i<=32;++i)

    Ist übrigens Falsch, da hier 33 Elemente durchlaufen werden.

    Es werden nur 32 Elemente durchlaufen, da beim ersten Mal die 0 zur 1 wird.
    Naja, das ++i würd ich in ner Schleife auch nicht machen, aber das ist eh Geschmackfrage..

    Hä?



  • DocJunioR schrieb:

    Es werden nur 32 Elemente durchlaufen, da beim ersten Mal die 0 zur 1 wird.
    Naja, das ++i würd ich in ner Schleife auch nicht machen, aber das ist eh Geschmackfrage..

    Nein. Es werden 33 Elemente durchlaufen. Egal ob du ++i oder i++ schreibst, beides wird erst am Ende eines Schleifendurchlaufs ausgeführt.

    @Raptor
    In manchen Situationen macht es schon Sinn, für Array Grössen 2er Potenzen zu nehmen.
    Bsp 1

    char a[31];
    char b[31];
    //...
    memcpy(a, b, 31);
    

    Eine x86-32 CPU zB muss hier 7 Dwords und 3 Bytes kopieren. Das kann man natürlich nicht in einem Schritt machen.
    Bsp 2

    char a[32];
    char b[32];
    //...
    memcpy(a, b, 32);
    

    Hier kann die CPU einfach 8 Dwords kopieren. Das ist im Normalfall etwas schneller als Bsp 1.

    Aber wie Kyon schon sagte, zuerst ist der grundlegende Algo zu optimieren bevor man sich an solche Detailarbeit macht.



  • Vielen Dank fuer die Antworten.

    @Kyon:

    Aber dazu ggf. mehr auf Anfrage.. 😉

    Das lass ich mir doch nicht zweimal sagen. Ich wuerde mich sehr freuen, wenn du dazu noch mehr Infos/Links haettest. 🙂


Anmelden zum Antworten