C++ 防止C+中矢量化的数学函数+;
我有一个类似下面的代码,我希望将其矢量化。 我使用intel advisor分析了整个代码。 它说我不能矢量化这个,因为它有数学函数。 当然,它指出了循环中使用的sin和cos函数C++ 防止C+中矢量化的数学函数+;,c++,vectorization,C++,Vectorization,我有一个类似下面的代码,我希望将其矢量化。 我使用intel advisor分析了整个代码。 它说我不能矢量化这个,因为它有数学函数。 当然,它指出了循环中使用的sin和cos函数 // 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_d
// 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), 0, plus<double>());
double Ai = std::accumulate(begin(Ai_elem), end(Ai_elem), 0, plus<double>());
如何在不使用“英特尔短向量数学库”的情况下对此循环进行向量化
代码:
(尺寸j=0;jAr+=
和Ai+=
术语阻止了矢量化,因为这意味着j=2
处的输出将取决于j=1
的输出。如果Ar
和Ai
只是输出,则可以将它们设置为数组,并在运行循环后对它们求和
// 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), 0, plus<double>());
double Ai = std::accumulate(begin(Ai_elem), end(Ai_elem), 0, plus<double>());
//初始化为0
双Ar_元素[NA]={0.0};
双元素[NA]={0.0};
对于(尺寸j=0;j
您的三角计算是否需要完全精确?您是否收到英特尔顾问的任何信息?请把它包括在问题中。为什么您认为sin
和cos
会阻止矢量化?p\u数据的排列也不理想。计算每个p
需要对3 x N
块进行转置或水平加法。Intel advisor表示循环没有矢量化。“英特尔顾问建议”选项卡上显示:存在标量数学函数调用。循环体中的数学函数阻止编译器有效地向量化循环。通过启用矢量化数学调用提高性能。他们的解决方案是:1)使用英特尔短向量数学库进行向量内部函数。2) 使用带有矢量化SVML函数的Glibc库。我想知道是否还有其他的可能性。谢谢你的解决方案。我知道,那里有一种依赖。我在考虑“pragma omp simd reduce”。然而,数学函数也阻止了矢量化。你有什么解决办法吗?你可以看看。但我更感兴趣的是,为什么你们认为正反两面会阻止simd的减少。你怎么知道这段代码没有矢量化?英特尔顾问说循环没有矢量化。“英特尔顾问建议”选项卡上显示:存在标量数学函数调用。循环体中的数学函数阻止编译器有效地向量化循环。通过启用矢量化数学调用提高性能。他们的解决方案是:1)使用英特尔短向量数学库进行向量内部函数。2) 使用带有矢量化SVML函数的Glibc库。我想知道是否还有其他可能性。您可以使用#pragma omp parallel for
“矢量化”循环,但我认为这不是SIMD矢量化,只是线程化。但您的解决方案将被矢量化。顺便问一下,您启用OMP了吗?我认为您需要明确指定编译器开关(/openmp
在VS中)。我认为您在第二条评论中提供的链接有助于回答我的问题。我还没有打开-fopenmp选项。这可能就是英特尔顾问公司提出这一建议的原因。无论如何,感谢您的解决方案。