Author: Gerd Isenberg
Date: 14:14:19 10/01/04
Go up one level in this thread
On October 01, 2004 at 11:48:25, Dan Honeycutt wrote: >On October 01, 2004 at 11:14:43, Reinhard Scharnagl wrote: > >>On October 01, 2004 at 10:58:43, Dan Honeycutt wrote: >> >>>If I have an inline function, ie: >>> >>>_inline int Distance(int square1, int square2) >>> >>>which is going to return the max rank/file difference but is not going to alter >>>the arguements, would I be better off passing the arguements by reference, ie: >>> >>>_inline int Distance(int & square1, int & square2) >>> >>>so as to save having to make a copy of the arguements. Or would the compiler >>>figure that out on it's own since the function is inline? I'm using MS VC 6. >>> >> >>Well I am not a guru, but taking an int not by value does only make sense if >>the original data should be changed. Copying an address could never be faster >>than copying an int. And a good compiler will work within inline parts with the >>original variables not with copies. But may be I have not seen your problem yet. >> >>Reinhard. > >Hi Reinhard: >Let me clarify a bit. The body of Distance() looks like: > >return Max(RankDiff(square1, square2), FileDiff(square1, square2)); > >The calling function looks like: > >square1 = ... >square2 = ... >d = Distance(square1, square2); > >When the function is inlined I want: > >square1 = ... >square2 = ... >d = Max(RankDiff(square1, square2), FileDiff(square1, square2)); > >But do I get > >square1 = ... >square2 = ... >copy1 = square1; >copy2 = square2; >d = Max(RankDiff(copy1, copy2), FileDiff(copy1, copy2)); > >And if i do get the latter form, would a pass by reference be better? > Not if copy is a register "incarnation" of an int. mov ecx, [square1] mov edx, [square2] .... cmp ecx, edx jle ... Even without fastcall, in the first case two values are pushed on the stack, and inside the routine you can access the values immediatly via base or stack pointer: push square1 push square2 ... mov eax, [copy1] ; ebp/esp-K1 cmp eax, [copy2] ; ebp/esp-K2 jle ... With pointers or references you have to push memory addresses on the stack. Since there are no pointers/references to registers - there is no chance to keep square1,2 inside registers. Inside your routine, you don't have direct access to the values via base- or stackpointer, but only to the addresses. So you have first to load the pointer, the memory address, inside a register to access the date via this register. Each additional register needed increases the register pressure, causing more push/pop instructions to save registers temporary on the stack. push offset square1 ; or lea eax, square1; push eax push offset square2 ... mov esi, [ptrSquare1] ; ebp/esp-K1 mov eax, [esi] ; square1 mov esi, [ptrSquare2] ; ebp/esp-K2 cmp eax, [esi] ; square2 jle ... As you can see, there are at least two additional instructions. Btw. can you post your implementation of Max, RankDiff and FileDiff? I think with random or alternating squares with no easy pattern you may get some misspredictions, if you use up to three compares and conditional jumps per distance. Had you have a closer look on 0x88 square differences? Lookup table(s) e.g. with packed 32-bit structs for distance, taxi-distance and may be two other byte values with square related stuff is an option too, you may look for "UDR" or unique distance relationship with CCC search engine. Gerd >Thanks >Dan H
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.