为什么对于几乎相同的代码,矢量化的行为会有所不同
Why does vectorization behave differently for almost the same code?
以下是自由函数,但在第一种情况下,循环不是矢量化的,而是在其他情况下。为什么是?
#include <vector>
typedef std::vector<double> Vec;
void update(Vec& a, const Vec& b, double gamma) {
const size_t K = a.size();
for (size_t i = 0; i < K; ++i) { // not vectorized
a[i] = b[i] * gamma - a[i];
}
}
void update2(Vec& a, const Vec& b, double gamma) {
for (size_t i = 0; i < a.size(); ++i) { // vectorized
a[i] = b[i] * gamma - a[i];
}
}
void update3(Vec& a, size_t K, const Vec& b, double gamma) {
for (size_t i = 0; i < K; ++i) { // vectorized
a[i] = b[i] * gamma - a[i];
}
}
int main(int argc, const char* argv[]) {
Vec a(argc), b;
update(a, b, 0.5);
update2(a, b, 0.5);
update3(a, a.size(), b, 0.5);
return 0;
}
来自编译器的相关消息(VS2013):
1> c:homedimatrwstrw_s-v1.3trwstestvector.cpp(7) : info C5002: loop not vectorized due to reason '1200'
1> c:homedimatrwstrw_s-v1.3trwstestvector.cpp(13) : info C5001: loop vectorized
1> c:homedimatrwstrw_s-v1.3trwstestvector.cpp(19) : info C5001: loop vectorized
来自@tony的评论
原因1200:"循环包含循环的数据依赖性,以防止 矢量化。环路的不同迭代干扰每个 其他使矢量化循环会产生错误的答案,并且 自动矢量化器无法向自己证明没有这样的数据 依赖。"源
我想这是一些内部编译器实现问题,例如在哪个阶段自动向量器"启动",当时代码内部表示的状态是什么。当我在MSVC2017上尝试时,它与人们期望的更加一致。它自动化了 update()
和 update3()
,但不是 update2()
,其中14行给出了501的原因,该行为记录为:
感应变量不是局部的;或上限不是循环不变。
相关文章:
- 为什么 openmp 的并行不适用于矢量化色彩空间转换?
- GCC 4.8.2 自动矢量化由于 cout 而失败
- 为什么浮点数的矢量化比双精度更有效?
- GCC、CLANG 和 MSVC 的可视化C++自动矢量化要求
- 如何使 msvc 矢量化浮点添加?
- 我可以期望某些 STL 函数实现是可自动矢量化的吗?
- 当在循环中使用时,std::shared_ptr 对该循环的矢量化有任何影响吗?
- 矢量化图像处理
- MSVC 2017 是否支持具有自动矢量化的 AVX 512
- 矢量化对称矩阵
- 如何在块复制期间矢量化范围检查
- 是否可以使用G 或Clang -OpenMP获得矢量化报告
- 错误的矢量化代码会影响可伸缩性吗?
- C 矢量化双回路
- 如何将现有的矢量化函数与Intel编译器自动化的现有标量函数相关
- 用于自动矢量化的展开指针增量循环
- 这是矢量化的良好实践吗
- 对于使用 C 样式指针矢量化的循环,但不使用迭代器
- SSE2 矢量化和虚拟机
- 为什么对于几乎相同的代码,矢量化的行为会有所不同