Optimierungshilfe gesucht für Array und Zeiger



  • Hi

    Habe mit dem Profiler gemerkt, das ich viele Aufrufe auf den Operator[] einer Klasse verbringe. Der ganze Code ist aus der FAQ zu 2D Arrays.
    Die Funktion sieht so aus

    int* operator[](int Zeile)
    {
        return & pArr[Zeile * Cols];
    }
    

    Dazu noch der Assemblercode

    ;int* operator[](int Zeile)
    ;{
    push ebp
    mov ebp,esp
    sub esp,44h
    push ebx
    push esi
    push edi
    mov [ebp-04h],ecx
    ;return & pArr[Zeile * Cols];
    mov eax,[ebp-04h]
    mov ecx,[ebp+08h]
    imul ecx,[eax+08h]
    mov edx,[ebp-04h]
    mov eax,[edx]
    lea eax,[eax+ecx*4]    ;Die meiste Zeit verbringt er hier
    ;}
    

    Kann mir bitte jemand helfen, den Zugriff aufs Array zu optimieren?
    Wär supi 🙂


  • Mod

    mach es inline und aktiviere die optimierung durch den compiler



  • So, das half, danke.
    Jetzt hängt er wo anders zu lange rum.
    Für die befüllung des 2D Arrays hab ich ne doppelte for Schleife:

    for( int i = 0; i < n; ++i ) {
        for( int j = 0; j < n; ++j ) {
            2DArray.set( i, j, 1 );
        }
    }
    
    ;for( int i = 0; i < n; ++i ) {
    mov [ebp-20h],00000000h
    jmp $+0bh (0x411c1f)
    mov eax,[ebp-20h]
    add eax,01h
    mov [ebp-20h],eax
    mov eax,[ebp-20h]
    cmp eax,[ebp-10h]
    jnl $+4eh (0x411c73)
    ;for( int j = 0; j < n; ++j ) {
    mov [ebp-24h],00000000h
    jmp $+0bh (0x411c39)
    mov eax,[ebp-24h]
    add eax,01h          ;hier verbraucht es die meiste Zeit
    mov [ebp-24h],eax
    mov eax,[ebp-24h]
    cmp eax,[ebp-10h]
    jnl $+32h (0x411c71)
    

    Kann ich wohl nicht optimieren oder?



  • @sc.
    mal so was zum thema sicherheit:

    int* operator[](unsigned int Zeile)
    {
        if (!pArr) return 0;
    
        if (Zeile >= Cols) return 0;
    
        return & pArr[Zeile * Cols];
    }
    

    unsigned aus dem einfachen Grund: Negative Arraypositionen gibt es nicht. Bei for-Schleifen die vorallem Rückwärtszählen ein sehr großes Sicherheitsrisiko!

    Testen ob pArr gültig ist, man möchte ja nicht auf nicht vorhandenen Speicher zugreifen

    Testen ob der Wert für Zeile gültig ist, man möchte ja keine Zugriffsverletzung machen.



  • for( int i = 0; i < n; ++i ) { 
        for( int j = 0; j < n; ++j ) { 
            2DArray.set( i, j, 1 ); 
        } 
    }
    

    Wenn du obiges noch optimieren willst, dann solltest du hier entweder die set-Methode inlinen oder aber eine z.B. Methode fill schreiben, welche alle Elementes des Arrays auf einen Wert (hier 'l') setzt. Dann sparst du den Methodenaufruf (Funktioniert aber nur, wenn 'l' konstant ist).



  • Nicht ganz richtig:

    ''' schrieb:

    @sc.
    mal so was zum thema sicherheit:

    int* operator[](unsigned int Zeile)
    {
        if (!pArr) return 0;
    
        if (Zeile >= Cols) return 0;
    
        return & pArr[Zeile * Cols];
    }
    

    Testen ob der Wert für Zeile gültig ist, man möchte ja keine Zugriffsverletzung machen.

    if (Zeile >= Cols) return 0;
    

    Ist falsch, sonst wäre ja ein Zugriff auf ein 10 x 3 Array an der Stelle [7][1] nicht möglich.

    Wenn schon (klingt sinnvoll...), dann:

    if (Zeile >= Rows) return 0;
    

    (bezieht sich alles auf 2. aus diesem Thread)

    Gruß,
    Dong


Anmelden zum Antworten