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]

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


Hello,

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.

Let me take a few (three) examples to explain my mind :

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)
    {
    //...
    }
  }
}

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.

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.

As you can imagine, I do not expect an exact answer to these questions by mail. My problem is to be able to know what the compiler can do, according to the level of optimization. Since I am certainly not qualified to understand the code generated by gcc, I would rather expect a little knowledge base (maintained by volunteers, of course ;-)), that would gather such information.

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 ?

Regards,

Pierre Chatelier


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