简单的多维数组解引用会很慢吗?

时间:2018-11-13 21:47:16

标签: c++ pointers gprof

我正努力了解从 gprof 获得的输出。

我在2D数组周围有一个简单的包装器类,需要在内存中保持连续。

它的构造函数和我用来访问值的方法是:

Array2d::Array2d(int size, double initialValue)
: mSize(size) {
    data = new double *[size];
    data[0] = new double[size * size];

    for (int i = 1; i < size; ++i) {
        data[i] = data[0] + i * size;
    }

    for (int i = 0; i < size; ++i) {
        for (int j = 0; j < size; ++j) {
            data[i][j] = initialValue;
        }
    }
}


double &Array2d::operator()(int i, int j) {
    return data[i][j];
}

在我正在处理的数字代码中,这是我从gprof获得的输出:

  %   cumulative   self              self     total           
 time   seconds   seconds    calls  ms/call  ms/call  name    
 49.33     34.80    34.80 43507867293     0.00     0.00  Array2d::operator()(int, int)
 18.05     47.53    12.73                             jacobi(Array2d&, Array2d&, int, int, double, double, double, int)

我很惊讶地看到几乎50%的运行时间都花在访问数组中的值上。

此Array2d类取代了std::vector<double>的使用,该方法要快得多。

我在这里看不懂什么?

1 个答案:

答案 0 :(得分:3)

  

我很惊讶地看到几乎50%的运行时间都花在了上面   从数组访问值。

在没有看到您的代码的情况下,我们不能说太多。很容易编写出单个调用所占百分比更高的代码。考虑

int main() { 
    while(true){ 
        foo(); 
    }
}

分析器会告诉您,有近100%的运行时间是在foo中花费的。这是否意味着foo很慢?不,我们不知道。

您从探查器获得的百分比可以提示您代码中的热点。如果您知道50%的时间都花在了一个特定的函数调用上,那么您就知道这是提高性能的最佳人选。如果优化此函数调用,则可以实现高达x2的加速(参见{amdahls law)。

另一方面,仅使用总运行时间的0.1%的函数可以提高1000倍,而对总运行时间没有重大影响。

无论您的元素访问速度是慢还是快,您都只能知道是否要实现第二种变体,将其他所有内容都保留在代码中,然后重复分析。导致百分比较高的变体效果更差。