【问题标题】:how to improve performance of 2d array in C++如何在 C++ 中提高二维数组的性能
【发布时间】:2016-11-05 13:55:59
【问题描述】:

我有一个会被调用数百万次的低级函数,所以它应该非常高效。当我在 Linux 中使用“gprof”时,我发现部分代码占用了函数总计算量的 60%(其余部分是求解三次方程的根)。这里Point是一个数据结构,有x和v,会被转换成矩阵供以后使用。这个想法是用第一行减去每一行。代码如下所示

    double x[4][3] = {0}, v[4][3] = {0};
    for (int i = 0; i < 4; ++i){
        for (int j = 0; j < 3; ++j){
            v[i][j] = Point[i]->v[j];
            x[i][j] = Point[i]->x[j];
        }
    }
    for (int i = 1; i < 4; ++i){
        for (int j = 0; j < 3; ++j){
            v[i][j] = v[0][j] - v[i][j];
            x[i][j] = x[0][j] - x[i][j];
        }
    }

谁能告诉我这段代码的问题?为什么它的表现如此糟糕?

【问题讨论】:

  • 如果你的代码有效,但可以改进,这里就不说了。请在 Code Review 上发布。
  • 您是否让编译器通过设置优化级别 3 或类似级别来做到最好?
  • Point 到底是什么?
  • 您正在初始化这些数组(x 和 v)三次,每次都用全新的值覆盖整个范围(第一行除外,您初始化两次)独立于上一个条目。然后问问自己,如果你真的需要这些本地副本,你能不能不简单地使用Point[i]-&gt;v[j] - Point[0]-&gt;v[j]i &gt; 0?因此,首先保存所有副本。
  • 感谢您的所有回复。我没有使用编译器优化,因为我想自己提高性能。我发现问题来自for循环。如果我在不使用 for 循环的情况下手动分配值,性能会变得更好。它只需要总计算时间的 20%。我对这个问题有点困惑。

标签: c++ arrays performance multidimensional-array


【解决方案1】:

您可以一次完成所有操作:

double x[4][3] = {
    { Point[0]->x[0], Point[0]->x[1], Point[0]->x[2] }
};
double v[4][3] = {
    { Point[0]->v[0], Point[0]->v[1], Point[0]->v[2] }
};

for (int i = 1; i < 4; ++i){
    for (int j = 0; j < 3; ++j){
        x[i][j] = x[0][j] - Point[i]->x[j];
        v[i][j] = v[0][j] - Point[i]->v[j];
    }
}

您甚至可以将其提升到一个新的水平,并将整个内容放入 x 和 v 的初始化程序中。

或者,如果Point 中的x 和v 都是连续数组:

double x[4][3], v[4][3]; // no init

// fill entire arrays
for (int i = 0; i < 4; ++i){
    memcpy(x[0], Point[0]->x, sizeof(x[0]));
    memcpy(v[0], Point[0]->v, sizeof(v[0]));
}

for (int i = 1; i < 4; ++i){
    for (int j = 0; j < 3; ++j){
        x[i][j] -= Point[i]->x[j];
        v[i][j] -= Point[i]->v[j];
    }
}

【讨论】:

  • 我按照您的建议进行了修改,但这并没有解决问题。有趣的是,“memcpy”函数甚至比手动分配值需要更多时间。展开双循环还可以提高性能。当然,这会牺牲可读性。
猜你喜欢
  • 1970-01-01
  • 2014-01-31
  • 2011-04-26
  • 1970-01-01
  • 2023-04-02
  • 2020-11-21
  • 2010-11-17
  • 1970-01-01
  • 2016-09-27
相关资源
最近更新 更多