简体   繁体   中英

Reducing non-static member function overhead

I have a computational physics code (finite difference) that performs operations (derivatives) on large arrays of data (solution fields and coefficient fields). The coefficient data is stored as an array of Model objects with an overloaded () operator. The following class is an example of what I am trying to do:

class Model
{
public: 
    inline double operator () (double field)
    {
        return alpha*field;
    }
private:
double alpha ;
}

The application would use an array of Models :

std::vector<Model> models; // array of models
std::vector<double> input;
std::vector<double> output;
...    
for (int i = 0; i < models.size(); i++)
{
    output[i] = models[i](input[i]);
} 

The problem is that there is a significant overhead from using the () operator.

I've profiled the code as-is, and then again where I removed the () operator and wrote the code inline. (I am using g++ 7.3.0., running on Ubuntu 18.04). I am compiling with -Winline and g++ does not complain that it cannot inline the function.

I have also tried using a static function in place of the () operator, and that did not have the same overhead. Unfortunately a static function cannot access member variables. Other posts indicate that this should not be a problem ( eg C++ Non-static member functions overhead ) but it certainly seems to be here.

So my question is: where is the overhead coming from with this non-static member function?

The difference between static and non-static is the this pointer. The code is shared between all instances, but there is an implicit argument to the function to access the members of the class. So there is no memory overhead like the question you refer but there is a small cost in time due to passing of this , and the pointer dereference to access the member variable. You could check the generated assembly file to make sure it's inline.

Suggestions to speed up the execution:

  • Use compiler optimizations
  • Use Parallelism: C++ Threads or OpenMP are easy options here
  • Change your design to use a vector of alphas and remove the class, then you could perhaps use SIMD

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM