This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Optimization/clarity coding : what is gcc able to do for me ?


Pierre Chatelier <pierre.chatelier@club-internet.fr> writes:

> The more gcc gets optimized, the more I wonder how to be a good
> coder. In fact, it seems that in many cases, I should better write
> "basic & simple" code and let the compiler optimize it for me, because
> writing complex code would discourage the compiler to understand and
> modify it.

Ideally the compiler will work either way.  The main reason to write
"basic & simple" code is that it will be easier for other people to
understand it.

> Nested loop : what about variable creation at each iteration ?
> Usually, we are told that the following form is bad because "j" is
> created at each "i" iteration
> for(int i=0 ; i<n ; ++i)
> {
>    for(int j=0 ; j<m ; ++j)
>    {
>    //...
>    }
> }
> 
> This one would theoretically be better :
> { //block to limit the scope of j
>    int j = 0;
>    for(int i=0 ; i<n ; ++i)
>    {
>      for(j=0 ; j<m ; ++j)
>      {
>      //...
>      }
>    }
> }

Whoever told you that was either confused or dealing with a very
simple compiler.  No modern compiler is going to care whether you
declare 'j' inside or outside of the loop on 'i'.

> The other example with temporary nested variables:
> Is it really bad to write :
> for(int i=0 ; i<n ; ++i)
> {
>    double tmp1 = ....some complex temporary calculations...
>    double tmp2 = ....some complex temporary calculations...
>    array[i] = tmp1+tmp2;
> }
> 
> instead of
> 
> {
>    double tmp1 = 0;
>    double tmp2 = 0;
>    for(int i=0 ; i<n ; ++i)
>    {
>      tmp1 = ....some complex temporary calculations...
>      tmp2 = ....some complex temporary calculations...
>      array[i] = tmp1+tmp2;
>    }
> }
> 
> As you can see in this two examples, I wonder if the compiler is able
> to see that the variables could be created outside the block. If I do
> it by myself, I am ensured that they will be created once, but perhaps
> it will be worse than the compiler can do for some obscure cache
> considerations.

Again it really doesn't matter.  At a very basic level, the compiler
works by translating C code into a simple language which can be easily
optimized.  In that simple language both code samples above are going
to be pretty much the same.

> A last (more or less stupid) example:
> 
> Is it better to write :
> 
> vector<int> v(1000);
> for(int i=0 ; i<v.size() ; ++i)
>    v[i] = i;
> 
> or rather :
> 
> size_t size = 1000;
> vector<int> v(size);
> for(int i=0 ; i<size ; ++i)
>    v[i] = i;
> 
> In this last example, the question is about how the compiler can
> guess, thanks to inlining and other things, that "size" won't be
> modified in the loop, and that it does not have to call "size()" at
> each iteration. This example may not be very relevant, because
> "size()" is certainly an inlined accessor to a private attribute, so
> that there should not be many performance regression. The question
> still arises for me, because I do not know if it will be more
> efficient to access a local variable "size" or the "distant" size
> attribute of the object.

Here, it depends.  As you say, in the first example you are calling a
function at each loop iteration.  For a simple function like v.size(),
in a simple loop like this, the compiler will know that it doesn't
have to call the function every time.  In more complex cases, it
depends.  In the general case, the compiler will not be able to
determine that the result of calling the function does not change, and
it will have to call the function each time.  You can help gcc make
this type of determination by using the 'const' or 'pure' attributes;
see the section on C extensions in the manual.

> As a conclusion, I would say that such information would be great to
> help people change their coding habits, so that the compiler would not
> be obstructed by bad old methods. And this makes me introduce a last
> question : since old habits may now be obstacles to a good
> optimization, what about the relevance of old benchmarks ?

In typical cases, "old habits" should not be obstacles to good
optimization.  They may be obstacles to understanding the programs by
humans, but they shouldn't be obstacles for the compiler.

Ian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]