multi dimensional array example

K

Keith Thompson

Tom St Denis said:
Feeding the troll...

you ever think the compiler/compiler options could be to blame?
[snip]

Please don't. In my humble opinion, it has become clear that
responding to this particular troll will do no good. If nobody
responds to him, those who choose to killfile him can easily pretend
he doesn't exist.
 
S

Skybuck Flying

Frederick Williams said:
512^3 = 134217728

Ahhh the floating point calculations are to blame for me using 511, I
rounded it down to be on the safe side.

Is there some way I can use Windows Calculator to specify exactly: 134217728
to the power of 1/3 the result should be 512 ?

But then again I think I know a little bit about this finding of numbers..
the algorithms are probably not exact.... or maybe they can be exact by
using rational numbers.

Never knew how to use those though in high school, as usually I suck in math
and that includes operating my calculator, my real calculator is half
damaged...

So I am just using windows's calculator which is kinda nice... but can it do
what I want it to do ? =D

Bye,
Skybuck.
 
R

rossum

Hello,

How to convert this Delphi code for Win32 to C or C++ Win32 code ?

var
vArray : array of array of array of integer;

x,y,z : integer;

begin
SetLength( vArray, 200, 200, 200 );

for x := 0 to 199 do
begin
for y := 0 to 199 do
begin
for z := 0 to 199 do
begin
vArray[ x, y, z ] := 123456789;
end;
end;
end;

vArray := nil;
end;

Bye,
Skybuck.
1 Get a copy of Delphi.NET
2 Compile your code in Delphi.NET to give an MSIL file.
3 Use Reflector (http://www.aisto.com/roeder/dotnet/) to decompile
your MSIL into C++.NET

rossum
 
S

Skybuck Flying

Tom St Denis said:
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

**** GCC and all that shit lol that s even worse LOL no just kidding... it's
nice for making little stinking cross compilers LOL.

You want fucking assembler you got mister smart ass.

Stick this were the sun dont shine:

Fresh assembler straight out of Visual Studio .NET 2003 disassembly.

And I like this kinda of assembler much better than the shit that you
posted...

What the **** is that shit ?

This shit below represent the intel instruction set much more clear than
your posted SSSSHITTTT.

Now that we have some decent assembler shit we can go analyze, assimilate
and analizate it haha.

But you pretend to be the assembler smart ass so first I let you have a go
at it...

Because I have better things to do than analyze bullshit Visual Studio
shit...

And remember buddy/smartass hehe... I dont even know what the visual studio
optimizer settings are...

For all I care they off... I never really use the piece of shit... DUH...

It shouldn't matter anyway... default settings much always be good :p*

--- y:\c
testen\arrayaccesstest\arrayaccesstest\arrayaccesstest.cpp ------------
// ArrayAccessTest.cpp : Defines the entry point for the console
application.
//
#include "stdafx.h"
#include "windows.h"
#include "stdlib.h"
int _tmain(int argc, _TCHAR* argv[])
{
00411C80 push ebp
00411C81 mov ebp,esp
00411C83 sub esp,130h
00411C89 push ebx
00411C8A push esi
00411C8B push edi
00411C8C lea edi,[ebp-130h]
00411C92 mov ecx,4Ch
00411C97 mov eax,0CCCCCCCCh
00411C9C rep stos dword ptr [edi]
//int ***vArray;
int Tick1;
int Tick2;
int Interval;
int x,y,z;
int *vArray = new int[300*300*300];
00411C9E push 66FF300h
00411CA3 call operator new[] (411253h)
00411CA8 add esp,4
00411CAB mov dword ptr [ebp-128h],eax
00411CB1 mov eax,dword ptr [ebp-128h]
00411CB7 mov dword ptr [vArray],eax
// test 1
Tick1 = GetTickCount();
00411CBA mov esi,esp
00411CBC call dword ptr [__imp__GetTickCount@0 (42F18Ch)]
00411CC2 cmp esi,esp
00411CC4 call @ILT+1160(__RTC_CheckEsp) (41148Dh)
00411CC9 mov dword ptr [Tick1],eax
for (x=0; x<300; x++)
00411CCC mov dword ptr [x],0
00411CD3 jmp main+5Eh (411CDEh)
00411CD5 mov eax,dword ptr [x]
00411CD8 add eax,1
00411CDB mov dword ptr [x],eax
00411CDE cmp dword ptr [x],12Ch
00411CE5 jge main+0CAh (411D4Ah)
{
for (y=0; y<300; y++)
00411CE7 mov dword ptr [y],0
00411CEE jmp main+79h (411CF9h)
00411CF0 mov eax,dword ptr [y]
00411CF3 add eax,1
00411CF6 mov dword ptr [y],eax
00411CF9 cmp dword ptr [y],12Ch
00411D00 jge main+0C8h (411D48h)
{
for (z=0; z<300; z++)
00411D02 mov dword ptr [z],0
00411D09 jmp main+94h (411D14h)
00411D0B mov eax,dword ptr [z]
00411D0E add eax,1
00411D11 mov dword ptr [z],eax
00411D14 cmp dword ptr [z],12Ch
00411D1B jge main+0C6h (411D46h)
{
vArray[x+y*300+z*300*300] = 123456789;
00411D1D mov eax,dword ptr [y]
00411D20 imul eax,eax,12Ch
00411D26 add eax,dword ptr [x]
00411D29 mov ecx,dword ptr [z]
00411D2C imul ecx,ecx,12Ch
00411D32 imul ecx,ecx,12Ch
00411D38 add eax,ecx
00411D3A mov edx,dword ptr [vArray]
00411D3D mov dword ptr [edx+eax*4],75BCD15h
}
00411D44 jmp main+8Bh (411D0Bh)
}
00411D46 jmp main+70h (411CF0h)
}
00411D48 jmp main+55h (411CD5h)
Tick2 = GetTickCount();
00411D4A mov esi,esp
00411D4C call dword ptr [__imp__GetTickCount@0 (42F18Ch)]
00411D52 cmp esi,esp
00411D54 call @ILT+1160(__RTC_CheckEsp) (41148Dh)
00411D59 mov dword ptr [Tick2],eax
Interval = Tick2 - Tick1;
00411D5C mov eax,dword ptr [Tick2]
00411D5F sub eax,dword ptr [Tick1]
00411D62 mov dword ptr [Interval],eax
printf("%d\n", Interval );
00411D65 mov eax,dword ptr [Interval]
00411D68 push eax
00411D69 push offset string "%d\n" (42701Ch)
00411D6E call @ILT+1435(_printf) (4115A0h)
00411D73 add esp,8
// test 2
Tick1 = GetTickCount();
00411D76 mov esi,esp
00411D78 call dword ptr [__imp__GetTickCount@0 (42F18Ch)]
00411D7E cmp esi,esp
00411D80 call @ILT+1160(__RTC_CheckEsp) (41148Dh)
00411D85 mov dword ptr [Tick1],eax
for (x=0; x<300; x++)
00411D88 mov dword ptr [x],0
00411D8F jmp main+11Ah (411D9Ah)
00411D91 mov eax,dword ptr [x]
00411D94 add eax,1
00411D97 mov dword ptr [x],eax
00411D9A cmp dword ptr [x],12Ch
00411DA1 jge main+186h (411E06h)
{
for (y=0; y<300; y++)
00411DA3 mov dword ptr [y],0
00411DAA jmp main+135h (411DB5h)
00411DAC mov eax,dword ptr [y]
00411DAF add eax,1
00411DB2 mov dword ptr [y],eax
00411DB5 cmp dword ptr [y],12Ch
00411DBC jge main+184h (411E04h)
{
for (z=0; z<300; z++)
00411DBE mov dword ptr [z],0
00411DC5 jmp main+150h (411DD0h)
00411DC7 mov eax,dword ptr [z]
00411DCA add eax,1
00411DCD mov dword ptr [z],eax
00411DD0 cmp dword ptr [z],12Ch
00411DD7 jge main+182h (411E02h)
{
vArray[x*300*300+y*300+z] = 123456789;
00411DD9 mov eax,dword ptr [x]
00411DDC imul eax,eax,12Ch
00411DE2 imul eax,eax,12Ch
00411DE8 mov ecx,dword ptr [y]
00411DEB imul ecx,ecx,12Ch
00411DF1 add eax,dword ptr [z]
00411DF4 add ecx,eax
00411DF6 mov edx,dword ptr [vArray]
00411DF9 mov dword ptr [edx+ecx*4],75BCD15h
}
00411E00 jmp main+147h (411DC7h)
}
00411E02 jmp main+12Ch (411DACh)
}
00411E04 jmp main+111h (411D91h)
Tick2 = GetTickCount();
00411E06 mov esi,esp
00411E08 call dword ptr [__imp__GetTickCount@0 (42F18Ch)]
00411E0E cmp esi,esp
00411E10 call @ILT+1160(__RTC_CheckEsp) (41148Dh)
00411E15 mov dword ptr [Tick2],eax
Interval = Tick2 - Tick1;
00411E18 mov eax,dword ptr [Tick2]
00411E1B sub eax,dword ptr [Tick1]
00411E1E mov dword ptr [Interval],eax
printf("%d\n", Interval );
00411E21 mov eax,dword ptr [Interval]
00411E24 push eax
00411E25 push offset string "%d\n" (42701Ch)
00411E2A call @ILT+1435(_printf) (4115A0h)
00411E2F add esp,8
// test 3
Tick1 = GetTickCount();
00411E32 mov esi,esp
00411E34 call dword ptr [__imp__GetTickCount@0 (42F18Ch)]
00411E3A cmp esi,esp
00411E3C call @ILT+1160(__RTC_CheckEsp) (41148Dh)
00411E41 mov dword ptr [Tick1],eax
for (x=0; x<300*300*300; x++)
00411E44 mov dword ptr [x],0
00411E4B jmp main+1D6h (411E56h)
00411E4D mov eax,dword ptr [x]
00411E50 add eax,1
00411E53 mov dword ptr [x],eax
00411E56 cmp dword ptr [x],19BFCC0h
00411E5D jge main+1EEh (411E6Eh)
{
vArray[x] = 123456789;
00411E5F mov eax,dword ptr [x]
00411E62 mov ecx,dword ptr [vArray]
00411E65 mov dword ptr [ecx+eax*4],75BCD15h
}
00411E6C jmp main+1CDh (411E4Dh)
Tick2 = GetTickCount();
00411E6E mov esi,esp
00411E70 call dword ptr [__imp__GetTickCount@0 (42F18Ch)]
00411E76 cmp esi,esp
00411E78 call @ILT+1160(__RTC_CheckEsp) (41148Dh)
00411E7D mov dword ptr [Tick2],eax
Interval = Tick2 - Tick1;
00411E80 mov eax,dword ptr [Tick2]
00411E83 sub eax,dword ptr [Tick1]
00411E86 mov dword ptr [Interval],eax
printf("%d\n", Interval );
00411E89 mov eax,dword ptr [Interval]
00411E8C push eax
00411E8D push offset string "%d\n" (42701Ch)
00411E92 call @ILT+1435(_printf) (4115A0h)
00411E97 add esp,8
// test 4
Tick1 = GetTickCount();
00411E9A mov esi,esp
00411E9C call dword ptr [__imp__GetTickCount@0 (42F18Ch)]
00411EA2 cmp esi,esp
00411EA4 call @ILT+1160(__RTC_CheckEsp) (41148Dh)
00411EA9 mov dword ptr [Tick1],eax
for (x=(300*300*300)-1; x>=0; x--)
00411EAC mov dword ptr [x],19BFCBFh
00411EB3 jmp main+23Eh (411EBEh)
00411EB5 mov eax,dword ptr [x]
00411EB8 sub eax,1
00411EBB mov dword ptr [x],eax
00411EBE cmp dword ptr [x],0
00411EC2 jl main+253h (411ED3h)
{
vArray[x] = 123456789;
00411EC4 mov eax,dword ptr [x]
00411EC7 mov ecx,dword ptr [vArray]
00411ECA mov dword ptr [ecx+eax*4],75BCD15h
}
00411ED1 jmp main+235h (411EB5h)
Tick2 = GetTickCount();
00411ED3 mov esi,esp
00411ED5 call dword ptr [__imp__GetTickCount@0 (42F18Ch)]
00411EDB cmp esi,esp
00411EDD call @ILT+1160(__RTC_CheckEsp) (41148Dh)
00411EE2 mov dword ptr [Tick2],eax
Interval = Tick2 - Tick1;
00411EE5 mov eax,dword ptr [Tick2]
00411EE8 sub eax,dword ptr [Tick1]
00411EEB mov dword ptr [Interval],eax
printf("%d\n", Interval );
00411EEE mov eax,dword ptr [Interval]
00411EF1 push eax
00411EF2 push offset string "%d\n" (42701Ch)
00411EF7 call @ILT+1435(_printf) (4115A0h)
00411EFC add esp,8
delete []vArray;
00411EFF mov eax,dword ptr [vArray]
00411F02 mov dword ptr [ebp-11Ch],eax
00411F08 mov ecx,dword ptr [ebp-11Ch]
00411F0E push ecx
00411F0F call operator delete[] (4110AFh)
00411F14 add esp,4
getchar();
00411F17 mov eax,dword ptr [__iob+4 (42BD84h)]
00411F1C sub eax,1
00411F1F mov dword ptr [__iob+4 (42BD84h)],eax
00411F24 js main+2CAh (411F4Ah)
00411F26 mov ecx,dword ptr [__iob (42BD80h)]
00411F2C movsx edx,byte ptr [ecx]
00411F2F and edx,0FFh
00411F35 mov dword ptr [ebp-130h],edx
00411F3B mov eax,dword ptr [__iob (42BD80h)]
00411F40 add eax,1
00411F43 mov dword ptr [__iob (42BD80h)],eax
00411F48 jmp main+2DDh (411F5Dh)
00411F4A push offset __iob (42BD80h)
00411F4F call @ILT+890(__filbuf) (41137Fh)
00411F54 add esp,4
00411F57 mov dword ptr [ebp-130h],eax
return 0;
00411F5D xor eax,eax
}


Gjez... when I look at gcc assembler below that really makes me vomit and
puke BLURP.

Such disrespect for the intel instruction set reference manual !

I like disrecpect LOL.

GCC gets A STRAIGHT ROYAL ACE 10 from me for disrespect... LOL

UTTER AND UTTeR AND UTTER DISRESPECT ! =D


BEEEPBYE
Slybuxck out. haha.
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.

Tom
 
S

Skybuck Flying

rossum said:
Hello,

How to convert this Delphi code for Win32 to C or C++ Win32 code ?

var
vArray : array of array of array of integer;

x,y,z : integer;

begin
SetLength( vArray, 200, 200, 200 );

for x := 0 to 199 do
begin
for y := 0 to 199 do
begin
for z := 0 to 199 do
begin
vArray[ x, y, z ] := 123456789;
end;
end;
end;

vArray := nil;
end;

Bye,
Skybuck.
1 Get a copy of Delphi.NET
2 Compile your code in Delphi.NET to give an MSIL file.
3 Use Reflector (http://www.aisto.com/roeder/dotnet/) to decompile
your MSIL into C++.NET

Funny you mention this .NETSSHIT...

You not what the **** happened ?

I fucking accidently created a .NET console application... because that's
the default when I open Delphi 2006 and select a new application.

I FUCKING HATE .NET BULLSHITTTTTTTTTTTT but the .NET application ran fucking
fast.

I didn't even notice I was programming in .NET until I tried to fucking open
the fucking project with fucking Delphi 2006 win 32... it fucking complained
the .NET Profile or Whatever it's called is missssingg..

I was like what the **** ?!?!?! Is delphi going nuts or so... Is this really
that fucking buggy ? I was like screw this shit... I am just gonna open ALL
PERSONALTY yes that s what it s called.

I just opened the "Generic Personality" which is able to handle ALL SHIT.

And then it fucked worked.. I was like no fucking way ?! What the **** is
going on...

I fucking debugged the fucking piece of a shit.. AND TO MY HORROR I SAW ALL
THIS IL SHIT IN IT..

I was like what the **** is the world coming tooo ?!?!?!

How the **** is delphi producing IL shit when it's Win32 SHIT...

I also had to compile errors in the formatstring function... it doesn't have
a integer overloaded version or something.. .there for I need to write
numbers like 4 as 4.0 otherwise it nags... it has to be a double...

The .NET version doesn't have this problem... or maybe it's simple a lack of
type checking which accidently gets confused by me for a "new feature" lol.

Whatever the case may be... the end the story... I ofcourse fucking resaved
the project as Win32 and then it compiled just fine after 2 minor
adjustments.. yes the errors were in win32 as I mentioned above.. the
integer/double formatstring thingy...

Anyway it was a learnfull experience... which I must make sure never ever
fucking happens to me again because that was fucking NASTY !

NOOOOOOOOOOOOW TO GET BACK ON TOPIC ?!

WHAT THEN **** DOES IL HAVE TO DO WITH ALL THIS ?

WHY THE **** WOULD I WANT TO DECOMPILE IT ?!

WHAT DOES THAT HAVE TO DO WITH REWRITING IT FOR VISUAL STUDIO .NET 2003.

Ohhhhhhhmmaaaannnn

I just realized what it has to do with it

ABSOLUTELY FUCKING NOTHING.

YOU ARE JUST ONE CLUELESS MOTHERFUCKER OUT OF THOUSAND....

But that;'s ok... I DONT BLAME YOU...

IT S OK TO BE A CLUESLESS MOTERFUCKER LOL
'
THATN S WHY I AM AROUND LOL

*************

TO SET YOU STRAIGHT LOL

**************



NEWS FLASH:


Visual STudio .Net 2003 CAN ALSO BE USED FOR WIN32 DEVELOPMENT


END OF NEW FLASH

END OF SETTING YOU STRAIGHT YOU CLUELESS MOTHERFUCKER LOL

Hahaahahahahahahahahaahahahah

Maybe I ll stick around on this newsgroup..

IT S JUST TO FUNNNNNYYY LOL

Bye,
Skybuck.

But dont bet on it as I wrote before I have better things to do...

Gods I am almost passing out...

Time to take it easy and get some sleep or so.. <- timing code in brain
badly malfuncting/confused...

No not really..

MY WILL POWER IS JUST TO STRONG...

I JUST GO ON AND ON AND ON AND ON AND ON AND REFUSE TO GO OFFFFFFF
BYE BYE
SKYBUCK.

Yes.
 
M

Mark McIntyre

Skybuck Flying said:


You could start by apologising for your systematic and prolonged Usenet
abuse over several years. People aren't usually all that interested in
helping trolls with technical problems.

Richard,

--

_____________________
/| /| | |
||__|| | Please do not |
/ O O\__ | feed the |
/ \ | Trolls |
/ \ \|_____________________|
/ _ \ \ ||
/ |\____\ \ ||
/ | | | |\____/ ||
/ \|_|_|/ | _||
/ / \ |____| ||
/ | | | --|
| | | |____ --|
* _ | |_|_|_| | \-/
*-- _--\ _ \ | ||
/ _ \\ | / `
* / \_ /- | | |
* ___ c_c_c_C/ \C_c_c_c____________
 
T

Tom St Denis

Keith said:
Tom St Denis said:
Feeding the troll...

you ever think the compiler/compiler options could be to blame?
[snip]

Please don't. In my humble opinion, it has become clear that
responding to this particular troll will do no good. If nobody
responds to him, those who choose to killfile him can easily pretend
he doesn't exist.

Judging by his reply yeah ... hehehe He/she/it's been around sci.crypt
as well spouting the same sort of nonsense and replying to itself in
long streams of gibberish runons.

I just felt like dropping some logic on the thread and don't really
intend to reply to the dude in the near future.

I don't get what people like that have to prove. It isn't like their
gibberish is part of a convincing argument. So even if they had a
point to make it's lost in the delivery anyways... oh well...

Tom
 
F

Frederick Williams

Skybuck said:
Ahhh the floating point calculations are to blame for me using 511, I
rounded it down to be on the safe side.

Is there some way I can use Windows Calculator to specify exactly: 134217728
to the power of 1/3 the result should be 512 ?

The version on my PC (XP 5.1 SP 2) has an x^3 button and an Inv tick
box:
(1) Enter 134217728 into the window
(2) Tick Inv
(3) Press x^3
The result 512 appears in the window.
 
D

Dr J R Stockton

In alt.comp.lang.borland-delphi message
<[email protected]>, Fri, 24 Nov 2006
15:09:38, Frederick Williams
512^3 = 134217728

Not so; in 512*512*512 there are only two multiplications.

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

But if the answer is to be exactly 134217728, then 11585... must not be
truncated, and so the first multiplication will take infinite time.
 
R

Richard Heathfield

Dr J R Stockton said:
In alt.comp.lang.borland-delphi message
<[email protected]>, Fri, 24 Nov 2006
15:09:38, Frederick Williams


Not so; in 512*512*512 there are only two multiplications.

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

But if the answer is to be exactly 134217728, then 11585... must not be
truncated, and so the first multiplication will take infinite time.

There is, fortunately, another solution which can be performed precisely, in
finite time, using ordinary high school arithmetic, but first I should just
mention that I am using ^ to represent exponentiation for once, rather than
XOR.

The solution is, naturally enough, the number 134217728^0.25. Multiplying
this by itself once gives 134217728^0.5; the second multiplication gives
134217728^0.75, and the third gives 134217728^1.00, which is of course
equal to 134217728.

The trick is to leave 134217728^0.25 in that form, rather than try to
"simplify" it before doing the multiplications.
 
D

Dr J R Stockton

In alt.comp.lang.borland-delphi message
Sat said:
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
 
S

Skybuck Flying

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.
 
R

Richard Heathfield

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.
 
R

robertwessel2

Tom said:
Skybuck said:
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.
 
T

Tom St Denis

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
 
S

Skybuck Flying

Richard Heathfield said:
Skybuck Flying said:


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 :p* =D

Bye,
Skybuck.
 
S

Skybuck Flying

Skybuck Flying said:
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.
 
S

Skybuck Flying

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 :p =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.
 
R

robertwessel2

Skybuck said:
Skybuck Flying said:
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;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top