C ++中防止向量化的数学函数

问题描述

我有一个类似以下的代码,我希望将其向量化。 我使用英特尔顾问分析了整个代码。 它说我无法向量化它,因为它具有数学函数。 当然,它指出了循环中使用的sin和cos函数

如何在不使用intel短向量数学库的情况下向量化此循环?

代码

for (size_t j = 0; j < NA; ++j) {
    esf = sfs[j];
    x = p_data[3 * j];
    y = p_data[3 * j + 1];
    z = p_data[3 * j + 2];

    p = x * qx + y * qy + z * qz;

    Ar += esf * cos(p);
    Ai += esf * sin(p);
}

解决方法

它说我无法向量化,因为它具有数学功能。

实际上,Ar +=Ai +=这两个术语阻止了矢量化,因为这意味着j = 2的输出将取决于j = 1的输出。如果ArAi只是输出,则可以使它们成为数组,并在运行循环后对其求和。

// init to 0
double Ar_elem[NA] = {0.0};
double Ai_elem[NA] = {0.0};

for (size_t j = 0; j < NA; ++j) {
    esf = sfs[j];
    x = p_data[3 * j];
    y = p_data[3 * j + 1];
    z = p_data[3 * j + 2];

    p = x * qx + y * qy + z * qz;

    Ar_elem[j] = esf * cos(p);
    Ai_elem[j] = esf * sin(p);
}

//sum
double Ar = std::accumulate(begin(Ar_elem),end(Ar_elem),plus<double>());
double Ai = std::accumulate(begin(Ai_elem),end(Ai_elem),plus<double>());