Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Optimizing C code for speed

Author: Robert Hyatt

Date: 19:25:11 01/02/03

Go up one level in this thread


On January 01, 2003 at 18:02:35, Andreas Guettinger wrote:

>On January 01, 2003 at 13:25:30, Matt Taylor wrote:
>
>>On January 01, 2003 at 11:50:58, Lieven Clarisse wrote:
>>
>>>I was wondering if there is a good book about how to write efficient C code. I
>>>am not talking about algorithms, but the way *how* to write things, eg
>>>
>>>which is faster :
>>>do {}  while()    or     while () {}
>>>
>>>-------
>>>I know for instance that:
>>>
>>>ptr=&R[i];
>>>if((*ptr==3)||(*ptr==7)) {;}
>>>
>>>is faster then:
>>>
>>>if((R[i]==3)||(R[i]==7)) {;}
>>>
>>>Is there a good book that reviews all those kinds of tricks?
>>>
>>>regards,
>>>
>>>Lieven
>>
>>It varies per compiler. There is an even faster method for your second case:
>>
>>x = R[i];
>>if (x == 3 || x == 7) {;}
>>
>>The only way to know is to look at compiler output. I know for VC, the compiler
>>I use most often, it chokes on 64-bit manipulations, stack alignment > 4 bytes,
>>and small structures. It usually generates nice code with conditionals such as:
>>
>>int is_below(int x, int y)
>>{
>>    return (x < y ? 1 : 0);
>>}
>>
>>-Matt
>
>
>Why is
>
>int x = R[i];
>if (x == 3 || x == 7) {;}
>
>faster than
>
>if((R[i]==3)||(R[i]==7)) {;}
>
>Isn't the creation and assignment of x a waste of time?

This is going too far too quick.  They are _identical_ to a modern compiler.

Any good compiler first generates a dependency graph that shows when every
variable is used and when it is modified, in a graph form.  That lets it
notice that R[i] is used twice and not modified between uses, so it simply
loads R[i] once and does two comparisons with it.  In the code above
_neither_ will be faster than the other, unless you compile without any
optimization enabled at all.  Then Matt's code will definitely be better.

BTW if all you have is the following:

int X

...


X=R[i];
...

if ( X     &&      X) (omitted the comparison stuff

then X is _never_ allocated on the stack, X is never written to, and if you
use the debugger on the optimized code you can not print X because it was
eliminated.  Again, the dependency graph does this, by showing that X is set,
and then used, and that since it is local, it doesn't need to be available
beyond the point where it is last used, and if doesn't have to be written to
memory it won't be.

Again, without optimization, this is not true, of course, but who would compile
like that?  :)

>
>regards
>Andy



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.