/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
for(;;) vha pointers ? CONTINUED
Fra : aslak


Dato : 05-05-01 19:53

Tak for hjælpen på mit spm om en for lykke vha pointere!!!

int* i;
i = new int(0);

for( *i ; *i<SOME_NUM ; i++)
{
[gør et eller andet...]
}
delete i;

En helt anden sag er så om en sådan for-lykke med pointere er hurtigere end
en regulær for-lykke - værdien som pointeren i gemmer på ændres jo hurtigt
fx. 10^6 ved samme antal iterationer. Men rent teoretisk kan det så betale
sig mht hastighed?

mvh Rasmus Aslak



 
 
John Mørck Hansen (05-05-2001)
Kommentar
Fra : John Mørck Hansen


Dato : 05-05-01 23:45

"aslak" <familienkjaer@mail1.stofanet.dk> skrev
> Tak for hjælpen på mit spm om en for lykke vha pointere!!!
>
> int* i;
> i = new int(0);
>
> for( *i ; *i<SOME_NUM ; i++)
> {
> [gør et eller andet...]
> }
> delete i;
>
> En helt anden sag er så om en sådan for-lykke med pointere er hurtigere
end
> en regulær for-lykke - værdien som pointeren i gemmer på ændres jo hurtigt
> fx. 10^6 ved samme antal iterationer. Men rent teoretisk kan det så betale
> sig mht hastighed?

Det tror jeg ikke det kan, fordi variable i bl.a.. for-løkker bliver som
standart registret som 'register' altså direkte i cpu'ens register. CX
registeret så vidt jeg husker.

(John =





Kent Friis (06-05-2001)
Kommentar
Fra : Kent Friis


Dato : 06-05-01 20:46

Den Sun, 6 May 2001 00:44:31 +0200 skrev John Mørck Hansen:
>"aslak" <familienkjaer@mail1.stofanet.dk> skrev
>> Tak for hjælpen på mit spm om en for lykke vha pointere!!!
>>
>> int* i;
>> i = new int(0);
>>
>> for( *i ; *i<SOME_NUM ; i++)
>> {
>> [gør et eller andet...]
>> }
>> delete i;
>>
>> En helt anden sag er så om en sådan for-lykke med pointere er hurtigere
>end
>> en regulær for-lykke - værdien som pointeren i gemmer på ændres jo hurtigt
>> fx. 10^6 ved samme antal iterationer. Men rent teoretisk kan det så betale
>> sig mht hastighed?
>
>Det tror jeg ikke det kan, fordi variable i bl.a.. for-løkker bliver som
>standart registret som 'register' altså direkte i cpu'ens register. CX
>registeret så vidt jeg husker.

Det afhænger af compiler-implementationen. Jeg kunne fx. sagtens
forestille mig en compiler der putter den i R7 i stedet for.

Og bortset fra det, så ville det være dumt at lægge sig fast på CX til
for-løkker:

for(x=0; x<640; x++) for(y=0; y<480; y++) setpixel(x,y,(x+y)&255);

Mvh
Kent
--
Nu med en e-mail adresse der virker...

John Mørck Hansen (06-05-2001)
Kommentar
Fra : John Mørck Hansen


Dato : 06-05-01 22:42

"Kent Friis" <kfr@fleggaard.dk> skrev
> Det afhænger af compiler-implementationen. Jeg kunne fx. sagtens
> forestille mig en compiler der putter den i R7 i stedet for.
>
> Og bortset fra det, så ville det være dumt at lægge sig fast på CX til
> for-løkker:
>
> for(x=0; x<640; x++) for(y=0; y<480; y++) setpixel(x,y,(x+y)&255);

Det kan du godt fortælle mig. Jeg har aldrig været en guro i asm. Jeg kunne
bare huske at der vist var CX der blev brugt for 8-10 år siden ad jeg
kiggede på asm.


(John =



Mogens Hansen (06-05-2001)
Kommentar
Fra : Mogens Hansen


Dato : 06-05-01 07:47


"aslak" <familienkjaer@mail1.stofanet.dk> wrote in message
news:9d1i3p$gr1$1@sunsite.dk...
> Tak for hjælpen på mit spm om en for lykke vha pointere!!!
>
> int* i;
> i = new int(0);
>
> for( *i ; *i<SOME_NUM ; i++)
> {
> [gør et eller andet...]
> }
> delete i;
>
> En helt anden sag er så om en sådan for-lykke med pointere er hurtigere
end
> en regulær for-lykke - værdien som pointeren i gemmer på ændres jo hurtigt
> fx. 10^6 ved samme antal iterationer. Men rent teoretisk kan det så betale
> sig mht hastighed?

Det kommer an på hvad du vil opnå hurtigst muligt.
Rent teoretisk vil ovenstående give "undefined behaviour" (f.eks. crash)
væsentligt hurtigere end en traditionel for løkke.

Venlig hilsen

Mogens Hansen



Mogens Hansen (06-05-2001)
Kommentar
Fra : Mogens Hansen


Dato : 06-05-01 08:35

Lidt mere seriøst:

Generelt med optimering gælder de gamle råd:
* Lad være indtil der viser sig et behov. For tidlig optimering er
ondartet.
* _Mål_ hvor problemet er
* Prøv at løse problemet, og _mål_ for at sikre at det rigtige er blevet
rettet

Mange gamle "sandheder" gælder ikke længere: f.eks. at det er dyrt at bruge
floating point tal i stedet for heltal. Moderne CPU'ers performance hænger
meget sammen med deres cache og pipelines, som komplicerer tingene
væsentligt.

"aslak" <familienkjaer@mail1.stofanet.dk> wrote in message
news:9d1i3p$gr1$1@sunsite.dk...
> Tak for hjælpen på mit spm om en for lykke vha pointere!!!
>
> int* i;
> i = new int(0);
>
> for( *i ; *i<SOME_NUM ; i++)
> {
> [gør et eller andet...]
> }
> delete i;
>

I dit konkrete eksempel, er man bedre tjent med at bruge den ideomatiske
løsning
for(int i = 0; SOME_NUM != i; ++i) {
// ... do something
}

Det er nemmere at skrive rigtigt - for man skal ikke tænke over det. (Du har
lavet den samme fejl i den oprindelige tråd og i denne tråd).
Det er nemmere for kompileren at genkende mønsteret og optimere ud fra
genkendelsen.

Tag f.eks. følgende 2 funktioner og send dem igennem Microsoft Visual C++
V6.0 med Release style.

void foo(bool* bool_array, const size_t size)
{
for(size_t i = 0; size != i; ++i) {
bool_array[i] = true;
}
}

void bar(bool* bool_array, const size_t size)
{
size_t* ip = new size_t(0);
for(; size != *ip; ++(*ip)) {
bool_array[*ip] = true;
}
delete ip;
}

så vil du se at "foo" bliver implementeret helt uden løkker, idet den bruger
CPU'ens "rep stosd" instruktion hvor den lægger 4 bools ud af gangen - prøv
at slå den med håndkodet assembler!
"bar" derimod bliver implementeret med en del sammenligninger og jumps.

Jeg håber at det giver dig svaret på dit spørgsmål.


?foo@@YAXPA_NI@Z PROC NEAR ; foo, COMDAT

; 5 : for(size_t i = 0; size != i; ++i) {

mov ecx, DWORD PTR _size$[esp-4]
test ecx, ecx
je SHORT $L274
mov edx, ecx
push edi
mov edi, DWORD PTR _bool_array$[esp]
shr ecx, 2
mov eax, 16843009 ; 01010101H
rep stosd
mov ecx, edx
and ecx, 3
rep stosb
pop edi
$L274:

; 6 : bool_array[i] = true;
; 7 : }
; 8 : }

ret 0
?foo@@YAXPA_NI@Z ENDP ; foo



; COMDAT ?bar@@YAXPA_NI@Z
_TEXT SEGMENT
_bool_array$ = 8
_size$ = 12
?bar@@YAXPA_NI@Z PROC NEAR ; bar, COMDAT

; 12 : size_t* ip = new size_t(0);

push 4
call ??2@YAPAXI@Z ; operator new
add esp, 4
test eax, eax
je SHORT $L299
mov DWORD PTR [eax], 0
jmp SHORT $L300
$L299:
xor eax, eax
$L300:

; 13 : for(; size != *ip; ++(*ip)) {

mov ecx, DWORD PTR _size$[esp-4]
cmp ecx, DWORD PTR [eax]
je SHORT $L286
mov edx, DWORD PTR _bool_array$[esp-4]
push esi
$L284:

; 14 : bool_array[*ip] = true;

mov esi, DWORD PTR [eax]
mov BYTE PTR [esi+edx], 1
mov esi, DWORD PTR [eax]
inc esi
cmp ecx, esi
mov DWORD PTR [eax], esi
jne SHORT $L284
pop esi
$L286:

; 15 : }
; 16 : delete ip;

push eax
call ??3@YAXPAX@Z ; operator delete
pop ecx

; 17 : }

ret 0
?bar@@YAXPA_NI@Z ENDP ; bar


Venlig hilsen

Mogens Hansen



aslak (06-05-2001)
Kommentar
Fra : aslak


Dato : 06-05-01 18:30

Et par gode råd! Tak

"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:9d2uoj$ntv$1@news.cybercity.dk...
> Lidt mere seriøst:
>
> Generelt med optimering gælder de gamle råd:
> * Lad være indtil der viser sig et behov. For tidlig optimering er
> ondartet.
> * _Mål_ hvor problemet er
> * Prøv at løse problemet, og _mål_ for at sikre at det rigtige er blevet
> rettet
>
> Mange gamle "sandheder" gælder ikke længere: f.eks. at det er dyrt at
bruge
> floating point tal i stedet for heltal. Moderne CPU'ers performance hænger
> meget sammen med deres cache og pipelines, som komplicerer tingene
> væsentligt.
>
> "aslak" <familienkjaer@mail1.stofanet.dk> wrote in message
> news:9d1i3p$gr1$1@sunsite.dk...
> > Tak for hjælpen på mit spm om en for lykke vha pointere!!!
> >
> > int* i;
> > i = new int(0);
> >
> > for( *i ; *i<SOME_NUM ; i++)
> > {
> > [gør et eller andet...]
> > }
> > delete i;
> >
>
> I dit konkrete eksempel, er man bedre tjent med at bruge den ideomatiske
> løsning
> for(int i = 0; SOME_NUM != i; ++i) {
> // ... do something
> }
>
> Det er nemmere at skrive rigtigt - for man skal ikke tænke over det. (Du
har
> lavet den samme fejl i den oprindelige tråd og i denne tråd).
> Det er nemmere for kompileren at genkende mønsteret og optimere ud fra
> genkendelsen.
>
> Tag f.eks. følgende 2 funktioner og send dem igennem Microsoft Visual C++
> V6.0 med Release style.
>
> void foo(bool* bool_array, const size_t size)
> {
> for(size_t i = 0; size != i; ++i) {
> bool_array[i] = true;
> }
> }
>
> void bar(bool* bool_array, const size_t size)
> {
> size_t* ip = new size_t(0);
> for(; size != *ip; ++(*ip)) {
> bool_array[*ip] = true;
> }
> delete ip;
> }
>
> så vil du se at "foo" bliver implementeret helt uden løkker, idet den
bruger
> CPU'ens "rep stosd" instruktion hvor den lægger 4 bools ud af gangen -
prøv
> at slå den med håndkodet assembler!
> "bar" derimod bliver implementeret med en del sammenligninger og jumps.
>
> Jeg håber at det giver dig svaret på dit spørgsmål.
>
>
> ?foo@@YAXPA_NI@Z PROC NEAR ; foo, COMDAT
>
> ; 5 : for(size_t i = 0; size != i; ++i) {
>
> mov ecx, DWORD PTR _size$[esp-4]
> test ecx, ecx
> je SHORT $L274
> mov edx, ecx
> push edi
> mov edi, DWORD PTR _bool_array$[esp]
> shr ecx, 2
> mov eax, 16843009 ; 01010101H
> rep stosd
> mov ecx, edx
> and ecx, 3
> rep stosb
> pop edi
> $L274:
>
> ; 6 : bool_array[i] = true;
> ; 7 : }
> ; 8 : }
>
> ret 0
> ?foo@@YAXPA_NI@Z ENDP ; foo
>
>
>
> ; COMDAT ?bar@@YAXPA_NI@Z
> _TEXT SEGMENT
> _bool_array$ = 8
> _size$ = 12
> ?bar@@YAXPA_NI@Z PROC NEAR ; bar, COMDAT
>
> ; 12 : size_t* ip = new size_t(0);
>
> push 4
> call ??2@YAPAXI@Z ; operator new
> add esp, 4
> test eax, eax
> je SHORT $L299
> mov DWORD PTR [eax], 0
> jmp SHORT $L300
> $L299:
> xor eax, eax
> $L300:
>
> ; 13 : for(; size != *ip; ++(*ip)) {
>
> mov ecx, DWORD PTR _size$[esp-4]
> cmp ecx, DWORD PTR [eax]
> je SHORT $L286
> mov edx, DWORD PTR _bool_array$[esp-4]
> push esi
> $L284:
>
> ; 14 : bool_array[*ip] = true;
>
> mov esi, DWORD PTR [eax]
> mov BYTE PTR [esi+edx], 1
> mov esi, DWORD PTR [eax]
> inc esi
> cmp ecx, esi
> mov DWORD PTR [eax], esi
> jne SHORT $L284
> pop esi
> $L286:
>
> ; 15 : }
> ; 16 : delete ip;
>
> push eax
> call ??3@YAXPAX@Z ; operator delete
> pop ecx
>
> ; 17 : }
>
> ret 0
> ?bar@@YAXPA_NI@Z ENDP ; bar
>
>
> Venlig hilsen
>
> Mogens Hansen
>
>



Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408522
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste