1

我正在尝试计算 C++ 中二维数组的复数。代码运行非常缓慢,我已经缩小了 exp 函数的主要原因(即使我有 4 个嵌套循环,当我注释掉该行时程序运行速度很快)。

int main() {

    typedef vector< complex<double> > complexVect;
    typedef vector<double> doubleVect;

    const int SIZE = 256;
    vector<doubleVect> phi_w(SIZE, doubleVect(SIZE));
    vector<complexVect> phi_k(SIZE, complexVect(SIZE));
    complex<double> i (0, 1), cmplx (0, 0);
    complex<double> temp;
    int x, y, t, k, w;
    double dk = 2.0*M_PI / (SIZE-1);
    double dt = M_PI / (SIZE-1);
    int xPos, yPos;
    double arg, arg2, arg4;
    complex<double> arg3;
    double angle;
    vector<complexVect> newImg(SIZE, complexVect(SIZE));

    for (x = 0; x < SIZE; ++x) {
        xPos = -127 + x;
        for (y = 0; y < SIZE; ++y) {
            yPos = -127 + y;
            for (t = 0; t < SIZE; ++t) {
                temp = cmplx;
                angle = dt * t;
                arg = xPos * cos(angle) + yPos * sin(angle);
                for (k = 0; k < SIZE; ++k) {
                    arg2 = -M_PI + dk*k;
                    arg3 = exp(-i * arg * arg2);
                    arg4 = abs(arg) * M_PI / (abs(arg) + M_PI);
                    temp = temp + arg4 * arg3 * phi_k[k][t];
                }
            }
            newImg[y][x] = temp;
        }
    }
}

有没有办法可以提高计算时间?我尝试使用以下辅助函数,但没有明显帮助。

complex<double> complexexp(double arg) {
    complex<double> temp (sin(arg), cos(arg));
    return temp;
}

我正在使用 clang++ 编译我的代码

编辑:我认为问题在于我正在尝试计算复数。如果我只使用欧拉公式计算单独数组中的实部和虚部而不必处理复杂的类,会不会更快?

4

4 回答 4

1

也许这对你有用:

http://martin.ankerl.com/2007/02/11/optimized-exponential-functions-for-java/

于 2013-04-15T06:01:31.470 回答
0

我看过callgrind。我能找到的唯一边际改进(大小 = 50 时约为 1.3%)是改变:

temp = temp + arg4 * arg3 * phi_k[k][t];

temp += arg4 * arg3 * phi_k[k][t];
于 2013-04-15T16:43:32.233 回答
0

最昂贵的函数调用是 sin()/cos()。我怀疑使用复数参数调用 exp() 会在后台调用这些函数。

为了保持精度,该函数的计算速度会非常慢,而且似乎没有办法绕过它。但是,您可以用精度换取准确性,这似乎是游戏开发人员会做的事情:sin 和 cos 很慢,有替代方案吗?

于 2013-04-27T16:36:14.610 回答
-1

您可以将数字定义e为常量并使用std::pow()函数

于 2013-04-15T06:01:48.037 回答