Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2013-11

Array indexing vs. pointers

4 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jim Leonard

(Sorry if this isn't technical enough for the developer list, but it requires understanding of the underlying architecture so I thought it was appropriate.) I'm implementing something in FPC that will perform very many comparisons across sets of data, and would like to know whether or not FPC is more efficient with array indexing calculations vs. doing the pointer math myself. For example, I have a choice of doing either this:

   for b:=0 to num-1 do
     diff:=src^[b]-dst^[b];

...or this:

   for b:=0 to num-1 do begin
     diff:=src^-dst^;
     inc(src);
     inc(dst);
   end;

I read a few posts from 2010 and a post from 2013 that implies FPC's array index calcs are just a MUL and suboptimial; is this still the case? Which method produces faster code? A third way would be to copy data into a dynamic array and no pointer use at all, ie. "diff:=src[b]-dst[b];"... is this the fastest option?

(Eventually I will be writing performance-critical sections in assembler, but would like to avoid doing that during early phases of my project.)

Jim Leonard () Check out some trippy MindCandy: http://www.mindcandydvd.com/ A child borne of the home computer wars: http://trixter.oldskool.org/ You're all insane and trying to steal my magic bag!

Reply by email

Sven Barth
to Jim Leonard
Jim Leonard wrote 10 lines
(Sorry if this isn't technical enough for the developer list, but it requires understanding of the underlying architecture so I thought it was appropriate.) I'm implementing something in FPC that will perform very many comparisons across sets of data, and would like to know whether or not FPC is more efficient with array indexing calculations vs. doing the pointer math myself. For example, I have a choice of doing either this: for b:=0 to num-1 do diff:=src^[b]-dst^[b];

Don't you mean "src[b]-dst[b]"? At least that would be the correct code if you'd use FPC's implicit array indexing.

Show quoted text 14 lines
...or this: for b:=0 to num-1 do begin diff:=src^-dst^; inc(src); inc(dst); end; I read a few posts from 2010 and a post from 2013 that implies FPC's array index calcs are just a MUL and suboptimial; is this still the case? Which method produces faster code? A third way would be to copy data into a dynamic array and no pointer use at all, ie. "diff:=src[b]-dst[b];"... is this the fastest option?

The resulting instructions depend highly on the architecture. E.g. on x86 and m68k for the first case a MOV/MOVE instruction with a multiplier will be used while on other platforms this might involve an explicit multiplication. Also it will depend on the optimization level you use (e.g. on x86 the generated code for the first case is very different between -O2 and -O3). In the end you'd need to calculate the instruction timings to know whether one of the two is really faster than the other (and then you can compare that later on with your own implementation to check whether your code or the compiler's is faster ^^)

Regards,
Sven

Reply by email

Jim Leonard
to Sven Barth
Sven Barth wrote 9 lines
The resulting instructions depend highly on the architecture. E.g. on x86 and m68k for the first case a MOV/MOVE instruction with a multiplier will be used while on other platforms this might involve an explicit multiplication. Also it will depend on the optimization level you use (e.g. on x86 the generated code for the first case is very different between -O2 and -O3). In the end you'd need to calculate the instruction timings to know whether one of the two is really faster than the other (and then you can compare that later on with your own implementation to check whether your code or the compiler's is faster ^^)

I'm on x86. I was hoping for a little more than "profile it to find out" (for example, if pointers are optimized to be in indexing registers then it should be obvious that is fastest), but if I have to do that, then I guess that's what I'll have to do.

I suppose I can just write a short program that indexes data many different ways and then examine the asm output.

Jim Leonard () Check out some trippy MindCandy: http://www.mindcandydvd.com/ A child borne of the home computer wars: http://trixter.oldskool.org/ You're all insane and trying to steal my magic bag!

Reply by email

Martin
to Jim Leonard
Jim Leonard wrote 18 lines
On 11/7/2013 6:21 AM, Sven Barth wrote: > The resulting instructions depend highly on the architecture. E.g. on > x86 and m68k for the first case a MOV/MOVE instruction with a multiplier > will be used while on other platforms this might involve an explicit > multiplication. Also it will depend on the optimization level you use > (e.g. on x86 the generated code for the first case is very different > between -O2 and -O3). In the end you'd need to calculate the instruction > timings to know whether one of the two is really faster than the other > (and then you can compare that later on with your own implementation to > check whether your code or the compiler's is faster ^^) I'm on x86. I was hoping for a little more than "profile it to find out" (for example, if pointers are optimized to be in indexing registers then it should be obvious that is fastest), but if I have to do that, then I guess that's what I'll have to do. I suppose I can just write a short program that indexes data many different ways and then examine the asm output.

If you know the execution times of the underlying asm code, you can compile with -al
Then you get asm sources that you can look at.

You need to look through which optimization flags are available, and check different fpc versions.

IIRC (but not sure) fpc 2.6.0 would calculate the address of the array element in every run of the loop (via multiplication / from scratch)

I do not know if having a pointer, and increasing it (addition) is indeed faster (I would expect it, but ... / actually I did it on intel once and it was faster).

But looking at the asm, you can see if it is done or not

Reply by email