Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: C vs asm vs look-up optimization question

Author: Ricardo Gibert

Date: 08:43:37 01/23/02

Go up one level in this thread


On January 23, 2002 at 09:41:44, Tim Foden wrote:

>On January 22, 2002 at 23:00:33, Ricardo Gibert wrote:
>
>>On January 22, 2002 at 21:54:59, Ricardo Gibert wrote:
>>
>>>On January 22, 2002 at 21:21:57, Ricardo Gibert wrote:
>>>
>>>>On January 22, 2002 at 21:15:17, Ricardo Gibert wrote:
>>>>
>>>>>On January 21, 2002 at 16:16:10, Rafael Andrist wrote:
>>>>>
>>>>>>Well, I just rewrote the following function in assembler to get better speed (no
>>>>>>conditional jumps, less memory access) but the speedup was only minimal. A
>>>>>>possible problem of the asm code is, that the instructions doesn't pair well,
>>>>>>but it should be still considerably faster. Has anyone an idea what the problem
>>>>>>with the code below is? Should I perhaps throw this function out and use a
>>>>>>look-up-table?
>>>>>>
>>>>>>INLINE int Diag045Rot(const int iSqNr)
>>>>>>{
>>>>>>#if defined (Use_Asm)
>>>>>>// 0 <= iSqNr <= 63
>>>>>>__asm
>>>>>>{
>>>>>>  mov eax, iFeldNr;
>>>>>>  mov ah, al;
>>>>>>  and al, 007h;	//x (iFeldNr%8) --> al
>>>>>>  shr ah, 3;	//y (iFeldNr/8) --> ah
>>>>>>  sub al, ah;	//x-y --> al
>>>>>>  mov ah, al;	//    --> ah
>>>>>>  and ah, 080h;	//ah &= 0x80 (isolate sign bit)
>>>>>>  add ah, 080h;	//ah += 0x80 (setting the carry bit)
>>>>>>  adc ah, 0;	//ah += carry bit
>>>>>>  shl ah, 3;	//ah <<= 3;
>>>>>>  add al, ah;	//al += 8*(x-y < 0)
>>>>>>  xor ah, ah;
>>>>>>}
>>>>>>#else
>>>>>>  int x, y;
>>>>>>  x = iSqNr%8;
>>>>>>  y = iSqNr/8;
>>>>>>  return x-y + 8*(x-y < 0);
>>>>>
>>>>>Isn't this is the same as "return abs(x-y);"? If so, maybe the compiler will do
>>>>>a better job of optimizing with it.
>>>>
>>>>Oops! No it's not, but how about return (x-y+8)%8 ?
>>>
>>>Come to think of it, even better is "return (iSqNr-iSqNr/8)%8". I decided to
>>>test this and it works fine. You'll have to benchmark it to see if it produces
>>>faster code.
>>
>>Yes, this works, but I started to think about my suggestion of "return
>>(x-y+8)%8;" and suspected it would not work and it doesn't, since x may be less
>>than y of course.
>
>You could just use "return (x - y) & 7", instead.  :)

You could, but if we make the substitutions "x = iSqNr%8" and "y = iSqNr/8", we
get "return (iSqNr%8 - iSqNr/8) & 7", which has an extra redundant operation (4
total) compared to what I gave. Eliminating the redundant operation gives
"return (iSqNr - iSqNr/8) & 7", which is equivalent to what I gave.

BTW, I think it is better in general to let the compiler do the easy
"optimization" of "&7" rather than the programmer. It is easier to read in
complex expressions and avoids "precedence" errors when mixed with arithmetic
operations. In this case, it makes no difference at all, since it is only
applied to a parenthesized expression...until you or somebody else decides to
modify the program later on somehow ;-)

>
>Which makes the possible assembly code into:
>
>__asm
>{
>	mov	eax, square
>	mov	ebx, square
>	and	eax, 0x07	// eax = x

above line not needed!

>	shr	ebx, 3		// ebx = y
>	sub	eax, ebx	// eax = x - y
>	and	eax, 7		// ecx = (x - y) & 7
>}
>
>Cheers, Tim.
>
>>"return (iSqNr-iSqNr/8)%8" doesn't have this problem, so it
>>works like a charm. Only 3 operations rather than 6 in your original. BTW,
>>"x-y<0" counts as only 1 in yours, since x-y<0 is the same as x<y.
>>
>>>
>>>>
>>>>>
>>>>>Also, if you are using msvc6, it might help the compiler to insert an
>>>>>"__assume((0 <= iSqNr) && (iSqNr <= 63));". I don't use msvc6 myself, so I can't
>>>>>tell you if this really helps here.
>>>>>
>>>>>>#endif
>>>>>>}
>>>>>>
>>>>>>
>>>>>>Thanks in Advance
>>>>>>Rafael B. Andrist



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.