Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
134 views
in Technique[技术] by (71.8m points)

Operator () is time consuming (profiling in C++)

I have a user defined 2D array stored in a contiguous block of memory and thus overloaded the () operator.

void CheckIndex(int& i, int& j) const //checks for index out of bounds error 
{
  if ( i < -nghost || i >= cols_x+nghost ||
       j < -nghost || j >= rows_y+nghost )
    {
      std::cout << "Index out of bounds. Exiting."
        << std::endl;
      exit(EXIT_FAILURE);
    }
}

double& operator()(int i, int j) const
{
  CheckIndex(i,j);
  int jump = cols_x + 2*nghost;
  return mesh[ (i+nghost) + (j+nghost)*jump ];
}
double& operator()(int i, int j); //implementation same as above

I use my class in Monte Carlo simulations. After profiling I see that 15% of the time is spent in CheckIndex (which is called every time the operator() is called) and another 15% in operator()(int i,int j) const itself.

There is a similar issue here overloaded array subscript [] operator slow but I can't say that it helped since my overloaded operators return references and copying is avoided.

I tried to inline those functions but I am getting linker errors. However, I have also seen that most probably the compiler (g++) does this by itself.

Any ideas on what I can do?

question from:https://stackoverflow.com/questions/65882852/operator-is-time-consuming-profiling-in-c

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Bounds checking is well-known to be slow. Early CPU's even had a special function for it, so much of a performance impact does it cause. Even today, C++ defines std::vector::at to do bounds checking, and leaves the ordinary vector::operator[] unchecked.

This makes sense. Most of the critical use of operator[] is in loops, and there you only need to check the loop boundaries. The whole middle of the loop is safe.

C++ has further ways to make loops safe. Idioms like for (element:collection) don't force you to write the bounds, so you can't get it wrong either.

As a minor optimization, C++20 allows

  if ( i < -nghost || i >= cols_x+nghost ||
       j < -nghost || j >= rows_y+nghost )
    {
      [[unlikely]]
      std::cout << "Index out of bounds. Exiting.
";
      exit(EXIT_FAILURE);
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...