C ++ - 改进复数数学的计算时间

时间:2013-04-15 05:54:58

标签: c++ complex-numbers

我正在尝试用C ++计算2D数组的复数。代码运行速度非常慢,我已经将主要原因缩小为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 ++来编译我的代码

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

4 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

我看过callgrind。我能找到的唯一边际改善(约1.3%,尺寸= 50)是改变:

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

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

答案 2 :(得分:0)

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

为了保持精确度,该函数将非常缓慢地计算,并且似乎没有办法绕过它。但是,您可以精确地交换精确度,这似乎是游戏开发人员会做的事情:sin and cos are slow, is there an alternatve?

答案 3 :(得分:-1)

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