Computer Chess Club Archives


Search

Terms

Messages

Subject: another bug

Author: Vincent Diepeveen

Date: 13:30:51 09/16/01

Go up one level in this thread


On September 16, 2001 at 16:20:20, Vincent Diepeveen wrote:

>On September 16, 2001 at 09:28:49, Robert Hyatt wrote:
>
>>On September 15, 2001 at 22:33:18, Vincent Diepeveen wrote:
>>
>>>On September 15, 2001 at 20:38:36, Robert Hyatt wrote:
>>>
>>>>On September 15, 2001 at 16:17:52, Vincent Diepeveen wrote:
>>>>
>>>>>On September 15, 2001 at 15:23:29, Bruce Moreland wrote:
>>>>>
>>>>>>On September 15, 2001 at 14:30:40, Vincent Diepeveen wrote:
>>>>>>
>>>>>>>On September 15, 2001 at 11:14:36, Sune Fischer wrote:
>>>>>>
>>>>>>>>   bb ^= mask[to_square];        // remove the bit
>>>>>>>>
>>>>>>>>   movelist[++counter].from=from_square;
>>>>>>>>   movelist[counter].to=to_square;
>>>>>>>>   movelist[counter].piece=QUEEN;
>>>>>>>>   movelist[counter].capturedpiece=enemy.piece[board.id[to_square]];
>>>>>>>
>>>>>>>this looks ugly. Using a pointer here would be way faster.
>>>>>>
>>>>>>Not necessarily.  If the "counter" variable is enregistered by the compiler, you
>>>>>>end up with about the same thing as if you used a pointer, but it also depends
>>>>>>upon how large the elements of "movelist" are.
>>>>>
>>>>>If compilers optimized very well, then our problems would be solved Bruce,
>>>>>we could go write our programs in JAVA or C++ and let the compiler handle
>>>>>the problems of not allocating and removing objects.
>>>>>
>>>>>Also we would be able to use old Qbasic code in a very efficient way then.
>>>>>
>>>>>That's not what happens however. Usual it's smart to NOT trust the compiler.
>>>>>
>>>>>When patterns get complex then i saw that visual c++ makes huge optimization
>>>>>errors.
>>>>>
>>>>>Like if i check for 2 non-array/pointer entities for being zero:
>>>>>
>>>>>if( a & b )
>>>>>  then do this and that;
>>>>>
>>>>>to produce some crap assembly:
>>>>>  CMP EAX,0
>>>>>  JNZ LOOP
>>>>>  CMP EDX,0
>>>>>  JNZ LOOP1
>>>>>
>>>>>Now already people will complain: "you don't need special CMP for
>>>>>2 different statements". Well they're right.
>>>>>
>>>>>In fact you don't need 2 compares even. All you need is something
>>>>>primitive like:
>>>>>
>>>>>  ADD EAX,EDX
>>>>>  CMP EAX,0
>>>>>  JNZ LOOP1
>>>>>
>>>>
>>>>
>>>>That would be terribly dangerous, and if a is 1 and b is -1 you will screw
>>>>up badly.  The compiler can't possibly know that it can do that unless a and
>>>>b are unsigned.  And it would be dangerous there as there are two non-zero
>>>>constants you can add and get zero in an unsigned integer.
>>>>
>>>>The compiler would need special information to be able to do the above
>>>>safely, otherwise the world would be debugging some of the strangest bugs
>>>>anyone ever saw...
>>>
>>>Yeah sorry, there were a few bugs in my example code.
>>>
>>>It should read:
>>>  if ( a && b )
>>>
>>>versus
>>>
>>>  if( a | b )
>>>
>>
>>that doesn't fix a thing.  If a=1, and b=-1, then you _still_ get a zero
>>result which is wrong in the context of a && b.
>
> 0b11111111111111 | 0b000000001 =  something
>
>So you can't go wrong.

Another bug, shows why i would prefer the compiler doing it!

 if( !a && !b )

that might be the same like:
  if( a | b )

And as we know any term we can evaluate with ! somehow.

  if( a == 3 && b == 5 )

that's the same like:

  if( (a-3) == 0 && (b-5) == 0 )

So that's the same like:

  if( !(a-3) && !(b-5) )

So that deduces to something like:

  if( (a-3)|(b-5) )

That directly shows why i would prefer the compiler do it,
because source code that shows something like:
  if( (a-3)|(b-5) )

that kind of source code is hard to read what you planned to do there,
not very good for maintainability!

Whereas i can reread easily:
  if( a == 3 && b == 5 )

Now of course a major problem is that nearly all operations are
array operations.

 if( board[sq_something] == bishop && board[sq_else] == anything )

Now compiler builders will for optimizing assume that perhaps
  board[sq_else] == anything
will give an exception so they won't optimize this with CMOV* a look
like instructions. Nor won't they optimize it to a single branch for the
same reason.

This where usually the source code writer KNOWS that in this pattern it's
impossible to get an exception. Regrettably there is no way in telling in
C to the compiler somehow that it can optimize assume that not a single
illegal array element will be touched by these conditions for this particular
'if then else'.

I'm really missing this, because i think this is the main speedadvantage
which one has in assembly over C code nowadays. It's at least a factor of 2
in DIEP.

Vincent

>>
>>
>>
>>>
>>>>
>>>>
>>>>>However i would need to learn assembly for this or i must rewrite
>>>>>my C code. The compiler isn't smart Bruce. The compiler is very stupid
>>>>>when talking about source connections. So i have to write:
>>>>>  if( a+b )
>>>>>    then do this and that;
>>>>>
>>>>>>Using pointers will usually help the compiler out, because it can just indirect
>>>>>>through a value, rather than having to deal with scaling the value and adding it
>>>>>>to a constant.  But in some circumstances, scaling it and adding it to a
>>>>>>constant is free.
>>>>>
>>>>>In general the above construction makes no sense. Optimizing it with a
>>>>>pointer is always safer!
>>>>>
>>>>>>bruce



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.