Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > multi dimensional array example

Reply
Thread Tools

multi dimensional array example

 
 
Dr J R Stockton
Guest
Posts: n/a
 
      11-25-2006
In alt.comp.lang.borland-delphi message
<(E-Mail Removed) id>, Sat, 25 Nov 2006
14:46:10, Dr J R Stockton <(E-Mail Removed)> wrote:

>But 11585.23750296... can be multiplied by itself three times to give

But 11585.23750296... can be multiplied twice by itself three times to
give
>the required answer; indeed, unless one is careless one gets the same
>answer every time.


--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
For news:borland.*, use their server newsgroups.borland.com ; but first read
Guidelines <URL:http://www.borland.com/newsgroups/guide.html> ff. with care.
 
Reply With Quote
 
 
 
 
Skybuck Flying
Guest
Posts: n/a
 
      11-26-2006
There is no logic in your reasoning.

I mention Visual Studio and you start posting GCC crap.

Where's the logic in that mister ?

Bye,
Skybuck.


 
Reply With Quote
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      11-26-2006
Skybuck Flying said:

> There is no logic in your reasoning.
>
> I mention Visual Studio and you start posting GCC crap.
>
> Where's the logic in that mister ?


Tom St Denis made his reasoning quite clear in that article. You just have
to read it all the way to the end.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
 
Reply With Quote
 
robertwessel2@yahoo.com
Guest
Posts: n/a
 
      11-27-2006

Tom St Denis wrote:
> Skybuck Flying wrote:
> > > ROTFL!

> >
> > Prove me wrong ?
> >
> > As long as you don't I am the one really laughing my ass off =D

>
> Feeding the troll...
>
> you ever think the compiler/compiler options could be to blame?
>
> GCC with "-O3 -fomit-frame-pointer" on an x86_64 box produced the
> following asm from this C source
>
> void blah(int *n)
> {
> int x, y, z;
>
> for (x = 0; x < 200; x++)
> for (y = 0; y < 200; y++)
> for (z = 0; z < 200; z++) n[x*200*200 + y *200 + z] = x+y+z;
> }
>
> .type blah, @function
> blah:
> .LFB2:
> xorl %r10d, %r10d
> .L2:
> movl %r10d, %r9d
> movq %rdi, %r8
> xorl %esi, %esi
> .p2align 4,,7
> .L5:
> leal (%r9,%rsi), %edx
> movq %r8, %rcx
> xorl %eax, %eax
> .p2align 4,,7
> .L3:
> addl $1, %eax
> movl %edx, (%rcx)
> addq $4, %rcx
> addl $1, %edx
> cmpl $200, %eax
> jne .L3
> addq $1, %rsi
> addq $800, %r8
> cmpq $200, %rsi
> jne .L5
> addq $1, %r10
> addq $160000, %rdi
> cmpq $200, %r10
> jne .L2
> ret
>
> (I purposefully turned off loop unrolling to show what GCC did).
>
> In this case, GCC removed the multiplications and did simple additions
> to get the correct offsets. My bet is MSVC is not doing that, instead
> they are doing three IMULs per iteration and hence the slowness.
>
> Hint: GCC basically correctly produces the optimal code for this and
> Delphi won't do any better.
>
> Case closed, move on.



FWIW... VS03 and VC05 both produced very similar code to your GCC
example. At least when optimize is actually turned on (-Ox).
Starbuck's code output appears to be identical to the non-optimized
compiler output.

 
Reply With Quote
 
Tom St Denis
Guest
Posts: n/a
 
      11-27-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> FWIW... VS03 and VC05 both produced very similar code to your GCC
> example. At least when optimize is actually turned on (-Ox).
> Starbuck's code output appears to be identical to the non-optimized
> compiler output.


Somehow that doesn't really surprise me....

Tom

 
Reply With Quote
 
Skybuck Flying
Guest
Posts: n/a
 
      11-29-2006

"Tom St Denis" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
> (E-Mail Removed) wrote:
>> FWIW... VS03 and VC05 both produced very similar code to your GCC
>> example. At least when optimize is actually turned on (-Ox).
>> Starbuck's code output appears to be identical to the non-optimized
>> compiler output.

>
> Somehow that doesn't really surprise me....


Maybe that's because it's the default setting of Visual Studio... ? Gje.

Bye,
Skybuck.


 
Reply With Quote
 
Skybuck Flying
Guest
Posts: n/a
 
      11-29-2006

"Richard Heathfield" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Skybuck Flying said:
>
>> There is no logic in your reasoning.
>>
>> I mention Visual Studio and you start posting GCC crap.
>>
>> Where's the logic in that mister ?

>
> Tom St Denis made his reasoning quite clear in that article. You just have
> to read it all the way to the end.


Yes and you would need a lepricon's brain to understand the reasoning as
well * =D

Bye,
Skybuck.


 
Reply With Quote
 
Skybuck Flying
Guest
Posts: n/a
 
      11-29-2006

"Skybuck Flying" <(E-Mail Removed)> wrote in message
news:ekjlqh$3lf$(E-Mail Removed)1.ov.home.nl...
>
> "Tom St Denis" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) oups.com...
>> (E-Mail Removed) wrote:
>>> FWIW... VS03 and VC05 both produced very similar code to your GCC
>>> example. At least when optimize is actually turned on (-Ox).
>>> Starbuck's code output appears to be identical to the non-optimized
>>> compiler output.

>>
>> Somehow that doesn't really surprise me....

>
> Maybe that's because it's the default setting of Visual Studio... ? Gje.
>


Besides from that I am used to seeing Delphi's extra debugging code... quite
easily to recgonize...

However I shall post the release assembler as well...so interested people
can compare debug code with assembler code and figure out why release code
is even slower for worst case scenerio..

int _tmain(int argc, _TCHAR* argv[])
{
00401000 sub esp,8
00401003 push ebx
00401004 push ebp
00401005 push esi
00401006 push edi
//int ***vArray;
int Tick1;
int Tick2;
int Interval;
int x,y,z;
int *vArray = new int[300*300*300];
00401007 push 66FF300h
0040100C call operator new[] (401133h)
// test 1
Tick1 = GetTickCount();
00401011 mov esi,dword ptr [__imp__GetTickCount@0 (407000h)]
00401017 add esp,4
0040101A mov ebp,eax
0040101C call esi
0040101E mov dword ptr [esp+14h],eax
00401022 mov ebx,ebp
00401024 mov dword ptr [esp+10h],12Ch
0040102C lea esp,[esp]
for (x=0; x<300; x++)
{
for (y=0; y<300; y++)
00401030 mov edx,ebx
00401032 mov edi,12Ch
00401037 jmp main+40h (401040h)
00401039 lea esp,[esp]
{
for (z=0; z<300; z++)
00401040 mov eax,edx
00401042 mov ecx,12Ch
00401047 jmp main+50h (401050h)
00401049 lea esp,[esp]
{
vArray[x+y*300+z*300*300] = 123456789;
00401050 mov dword ptr [eax],75BCD15h
00401056 add eax,57E40h
0040105B dec ecx
0040105C jne main+50h (401050h)
0040105E add edx,4B0h
00401064 dec edi
00401065 jne main+40h (401040h)
00401067 mov eax,dword ptr [esp+10h]
0040106B add ebx,4
0040106E dec eax
0040106F mov dword ptr [esp+10h],eax
00401073 jne main+30h (401030h)
}
}
}
Tick2 = GetTickCount();
00401075 call esi
Interval = Tick2 - Tick1;
00401077 sub eax,dword ptr [esp+14h]
printf("%d\n", Interval );
0040107B push eax
0040107C push offset string "%d\n" (40710Ch)
00401081 call printf (401399h)
00401086 add esp,8
// test 2
Tick1 = GetTickCount();
00401089 call esi
0040108B mov ebx,eax
for (x=0; x<300; x++)
{
for (y=0; y<300; y++)
{
for (z=0; z<300; z++)
{
vArray[x*300*300+y*300+z] = 123456789;
0040108D mov eax,75BCD15h
00401092 mov ecx,19BFCC0h
00401097 mov edi,ebp
00401099 rep stos dword ptr [edi]
}
}
}
Tick2 = GetTickCount();
0040109B call esi
Interval = Tick2 - Tick1;
0040109D sub eax,ebx
printf("%d\n", Interval );
0040109F push eax
004010A0 push offset string "%d\n" (40710Ch)
004010A5 call printf (401399h)
004010AA add esp,8
// test 3
Tick1 = GetTickCount();
004010AD call esi
004010AF mov ebx,eax
for (x=0; x<300*300*300; x++)
{
vArray[x] = 123456789;
004010B1 mov eax,75BCD15h
004010B6 mov ecx,19BFCC0h
004010BB mov edi,ebp
004010BD rep stos dword ptr [edi]
}
Tick2 = GetTickCount();
004010BF call esi
Interval = Tick2 - Tick1;
004010C1 sub eax,ebx
printf("%d\n", Interval );
004010C3 push eax
004010C4 push offset string "%d\n" (40710Ch)
004010C9 call printf (401399h)
004010CE add esp,8
// test 4
Tick1 = GetTickCount();
004010D1 call esi
004010D3 mov edi,eax
for (x=(300*300*300)-1; x>=0; x--)
004010D5 mov eax,19BFCBFh
004010DA lea ebx,[ebx]
004010E0 dec eax
{
vArray[x] = 123456789;
004010E1 mov dword ptr argc[eax*4],75BCD15h
004010E9 jns main+0E0h (4010E0h)
}
Tick2 = GetTickCount();
004010EB call esi
Interval = Tick2 - Tick1;
004010ED sub eax,edi
printf("%d\n", Interval );
004010EF push eax
004010F0 push offset string "%d\n" (40710Ch)
004010F5 call printf (401399h)
delete []vArray;
004010FA push ebp
004010FB call operator delete[] (401394h)
getchar();
00401100 mov eax,dword ptr [__iob+4 (40907Ch)]
00401105 add esp,0Ch
00401108 pop edi
00401109 pop esi
0040110A pop ebp
0040110B dec eax
0040110C pop ebx
0040110D mov dword ptr [__iob+4 (40907Ch)],eax
00401112 js main+120h (401120h)
00401114 inc dword ptr [__iob (409078h)]
return 0;
0040111A xor eax,eax
}

Bye,
Skybuck.


 
Reply With Quote
 
Skybuck Flying
Guest
Posts: n/a
 
      11-29-2006
And finally I ll quickly post Delphi's output.. no range checking info
anyway...

Delphi does require some options to be able to view the cpu window (which is
the same as visual studio's disassembly option).

Not sure which options are necessary.

Now you guys can admired Delphi's stuff I guess =D

Project1.dpr.245: begin
0040992C 55 push ebp
0040992D 8BEC mov ebp,esp
0040992F 83C4A8 add esp,-$58
00409932 53 push ebx
00409933 56 push esi
00409934 57 push edi
00409935 33DB xor ebx,ebx
00409937 895DFC mov [ebp-$04],ebx
0040993A 894DF0 mov [ebp-$10],ecx
0040993D 8955F4 mov [ebp-$0c],edx
00409940 8945F8 mov [ebp-$08],eax
00409943 8B7510 mov esi,[ebp+$10]
00409946 8D5DA8 lea ebx,[ebp-$58]
00409949 33C0 xor eax,eax
0040994B 55 push ebp
0040994C 687F9A4000 push $00409a7f
00409951 64FF30 push dword ptr fs:[eax]
00409954 648920 mov fs:[eax],esp
Project1.dpr.246: vLength[Dimension1Order] := Dimension1Size;
00409957 8B45F8 mov eax,[ebp-$08]
0040995A 897485B4 mov [ebp+eax*4-$4c],esi
Project1.dpr.247: vLength[Dimension2Order] := Dimension2Size;
0040995E 8B45F4 mov eax,[ebp-$0c]
00409961 8B550C mov edx,[ebp+$0c]
00409964 895485B4 mov [ebp+eax*4-$4c],edx
Project1.dpr.248: vLength[Dimension3Order] := Dimension3Size;
00409968 8B45F0 mov eax,[ebp-$10]
0040996B 8B5508 mov edx,[ebp+$08]
0040996E 895485B4 mov [ebp+eax*4-$4c],edx
Project1.dpr.251: SetLength( vArray, vLength[0], vLength[1], vLength[2] );
00409972 8B45BC mov eax,[ebp-$44]
00409975 50 push eax
00409976 8B45B8 mov eax,[ebp-$48]
00409979 50 push eax
0040997A 8B45B4 mov eax,[ebp-$4c]
0040997D 50 push eax
0040997E 8D45FC lea eax,[ebp-$04]
00409981 B903000000 mov ecx,$00000003
00409986 8B15F4984000 mov edx,[$004098f4]
0040998C E81FB8FFFF call @DynArraySetLength
00409991 83C40C add esp,$0c
Project1.dpr.253: vLongTick1 := GetTickCount;
00409994 E897C3FFFF call GetTickCount
00409999 33D2 xor edx,edx
0040999B 8945D8 mov [ebp-$28],eax
0040999E 8955DC mov [ebp-$24],edx
Project1.dpr.257: for Dimension1Index := 0 to Dimension1Size-1 do
004099A1 4E dec esi
004099A2 85F6 test esi,esi
004099A4 7C63 jl $00409a09
004099A6 46 inc esi
004099A7 8975C4 mov [ebp-$3c],esi
004099AA C745E400000000 mov [ebp-$1c],$00000000
Project1.dpr.259: for Dimension2Index := 0 to Dimension2Size-1 do
004099B1 8B450C mov eax,[ebp+$0c]
004099B4 48 dec eax
004099B5 85C0 test eax,eax
004099B7 7C48 jl $00409a01
004099B9 40 inc eax
004099BA 8945C0 mov [ebp-$40],eax
004099BD 33C9 xor ecx,ecx
Project1.dpr.261: for Dimension3Index := 0 to Dimension3Size-1 do
004099BF 8B4508 mov eax,[ebp+$08]
004099C2 48 dec eax
004099C3 85C0 test eax,eax
004099C5 7C34 jl $004099fb
004099C7 40 inc eax
004099C8 33D2 xor edx,edx
Project1.dpr.263: vIndex[Dimension1Order] := Dimension1Index;
004099CA 8B75F8 mov esi,[ebp-$08]
004099CD 8B7DE4 mov edi,[ebp-$1c]
004099D0 893CB3 mov [ebx+esi*4],edi
Project1.dpr.264: vIndex[Dimension2Order] := Dimension2Index;
004099D3 8B75F4 mov esi,[ebp-$0c]
004099D6 890CB3 mov [ebx+esi*4],ecx
Project1.dpr.265: vIndex[Dimension3Order] := Dimension3Index;
004099D9 8B75F0 mov esi,[ebp-$10]
004099DC 8914B3 mov [ebx+esi*4],edx
Project1.dpr.267: vArray[vIndex[0], vIndex[1], vIndex[2] ] := 123456789;
004099DF 8B75FC mov esi,[ebp-$04]
004099E2 8B3B mov edi,[ebx]
004099E4 8B34BE mov esi,[esi+edi*4]
004099E7 8B7B04 mov edi,[ebx+$04]
004099EA 8B34BE mov esi,[esi+edi*4]
004099ED 8B7B08 mov edi,[ebx+$08]
004099F0 C704BE15CD5B07 mov [esi+edi*4],$075bcd15
Project1.dpr.268: end;
004099F7 42 inc edx
Project1.dpr.261: for Dimension3Index := 0 to Dimension3Size-1 do
004099F8 48 dec eax
004099F9 75CF jnz $004099ca
Project1.dpr.269: end;
004099FB 41 inc ecx
Project1.dpr.259: for Dimension2Index := 0 to Dimension2Size-1 do
004099FC FF4DC0 dec dword ptr [ebp-$40]
004099FF 75BE jnz $004099bf
Project1.dpr.270: end;
00409A01 FF45E4 inc dword ptr [ebp-$1c]
Project1.dpr.257: for Dimension1Index := 0 to Dimension1Size-1 do
00409A04 FF4DC4 dec dword ptr [ebp-$3c]
00409A07 75A8 jnz $004099b1
Project1.dpr.272: vLongTick2 := GetTickCount;
00409A09 E822C3FFFF call GetTickCount
00409A0E 33D2 xor edx,edx
00409A10 8945D0 mov [ebp-$30],eax
00409A13 8955D4 mov [ebp-$2c],edx
Project1.dpr.275: if vLongTick2 < vLongTick1 then
00409A16 8B45D0 mov eax,[ebp-$30]
00409A19 8B55D4 mov edx,[ebp-$2c]
00409A1C 3B55DC cmp edx,[ebp-$24]
00409A1F 7507 jnz $00409a28
00409A21 3B45D8 cmp eax,[ebp-$28]
00409A24 7311 jnb $00409a37
00409A26 EB02 jmp $00409a2a
00409A28 7D0D jnl $00409a37
Project1.dpr.277: vLongTick2 := vLongTick2 + 4294967296;
00409A2A 8B45D0 mov eax,[ebp-$30]
00409A2D 8B55D4 mov edx,[ebp-$2c]
00409A30 42 inc edx
00409A31 8945D0 mov [ebp-$30],eax
00409A34 8955D4 mov [ebp-$2c],edx
Project1.dpr.282: vInterval := vLongTick2 - vLongTick1;
00409A37 8B45D0 mov eax,[ebp-$30]
00409A3A 8B55D4 mov edx,[ebp-$2c]
00409A3D 2B45D8 sub eax,[ebp-$28]
00409A40 1B55DC sbb edx,[ebp-$24]
00409A43 8945C8 mov [ebp-$38],eax
00409A46 8955CC mov [ebp-$34],edx
Project1.dpr.285: vArray := nil;
00409A49 8D45FC lea eax,[ebp-$04]
00409A4C 8B15F4984000 mov edx,[$004098f4]
00409A52 E865B7FFFF call @DynArrayClear
Project1.dpr.288: result := vInterval;
00409A57 8B45C8 mov eax,[ebp-$38]
00409A5A 8945E8 mov [ebp-$18],eax
00409A5D 8B45CC mov eax,[ebp-$34]
00409A60 8945EC mov [ebp-$14],eax
Project1.dpr.289: end;
00409A63 33C0 xor eax,eax

Bye,
Skybuck.


 
Reply With Quote
 
robertwessel2@yahoo.com
Guest
Posts: n/a
 
      11-29-2006

Skybuck Flying wrote:
> "Skybuck Flying" <(E-Mail Removed)> wrote in message
> news:ekjlqh$3lf$(E-Mail Removed)1.ov.home.nl...
> >
> > "Tom St Denis" <(E-Mail Removed)> wrote in message
> > news:(E-Mail Removed) oups.com...
> >> (E-Mail Removed) wrote:
> >>> FWIW... VS03 and VC05 both produced very similar code to your GCC
> >>> example. At least when optimize is actually turned on (-Ox).
> >>> Starbuck's code output appears to be identical to the non-optimized
> >>> compiler output.
> >>
> >> Somehow that doesn't really surprise me....

> >
> > Maybe that's because it's the default setting of Visual Studio... ? Gje.
> >

>
> Besides from that I am used to seeing Delphi's extra debugging code... quite
> easily to recgonize...
>
> However I shall post the release assembler as well...so interested people
> can compare debug code with assembler code and figure out why release code
> is even slower for worst case scenerio..
>
> int _tmain(int argc, _TCHAR* argv[])
> (...)



Given your usual incoherent posting style, it's unclear why you
actually posted all this code, but I'm guessing that you're still
seeing a performance difference.

Try accessing the arrays in the same order. Your C program is varying
the largest dimension first, and thus scattering references all over
the array, undoubtedly generating many cache misses. The Delphi
program varies the smallest dimension first, and thus nicely steps
sequentially through the array's storage, which caches quite well.

Array accesses always need to consider access order, and while both of
your programs vary the "third" index fastest, you've stored the array
in row major order in your Delphi program, but (strangely) in column
major order for the C version.

To properly compare these, you need to either change the Delphi program
to do:

vArray[ z, y, x ] := 123456789;

*Or* the C program to do:

vArray[z+y*200+x*200*200] = 123456789;

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
To convert a one dimensional array into a two dimensional array using C amrutha0303 Software 0 08-03-2010 10:02 PM
multi-dimensional arrays to 2-dimensional arrays Wirianto Djunaidi Ruby 2 04-29-2008 07:31 AM
multi dimensional array example Skybuck Flying C Programming 44 11-30-2006 05:24 AM
Multi-dimensional Array in Java? kk_oop Java 1 07-24-2004 11:23 PM
How do copy Strings from a single dimensional array to double dimensional array Venkat C++ 4 12-05-2003 09:23 AM



Advertisments