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 ausint* 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
-
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