【发布时间】:2014-06-16 05:32:22
【问题描述】:
我正在尝试让我的代码自动矢量化,但它不起作用。
int _tmain(int argc, _TCHAR* argv[])
{
const int N = 4096;
float x[N];
float y[N];
float sum = 0;
//create random values for x and y
for (int i = 0; i < N; i++)
{
x[i] = rand() >> 1;
y[i] = rand() >> 1;
}
for (int i = 0; i < N; i++){
sum += x[i] * y[i];
}
}
这里没有循环矢量化,但我真的只对第二个循环感兴趣。
我正在使用 Visual Studio Express 2013 并使用 /O2 和 /Qvec-report:2(报告循环是否已矢量化)选项进行编译。当我编译时,我收到以下消息:
--- Analyzing function: main
c:\users\...\documents\visual studio 2013\projects\intrin3\intrin3\intrin3.cpp(28) : info C5002: loop not vectorized due to reason '1200'
c:\users\...\documents\visual studio 2013\projects\intrin3\intrin3\intrin3.cpp(41) : info C5002: loop not vectorized due to reason '1305'
原因 '1305',如 HERE 所示,表示“编译器无法识别此循环的正确矢量化类型信息”。我不太确定这意味着什么。有什么想法吗?
将第二个循环分成两个循环后:
for (int i = 0; i < N; i++){
sumarray[i] = x[i] * y[i];
}
for (int i = 0; i < N; i++){
sum += sumarray[i];
}
现在上述循环中的第一个循环矢量化,但第二个循环没有,再次出现错误代码 1305。
【问题讨论】:
-
您要为哪个 SIMD 主机编译?可能是主机没有提供所需的指令(我怀疑您需要水平添加。您是否尝试将循环分成两部分:一个生成
sum[]向量,然后第二个循环添加sum[]中的元素?这至少可以缩小范围。 -
我不确定您所说的 SIMD 主机是什么意思。我的 CPU 是英特尔酷睿 i7。另外,真的很抱歉,但我误传第一个循环确实被矢量化了,这是不正确的。我已经更新了帖子和输出消息。感谢您的建议,现在将尝试打破循环。是否有必要将其设为向量还是可以使用 sum 数组?
-
打破循环并将相关信息添加到问题中。
-
尝试将“/arch:AVX”添加到命令行。它应该能够生成额外的 SIMD 指令。
-
@JonB.Jones:我的意思是,对于 SIMD 主机,您正在为什么 CPU 生成代码,有哪些 SIMD 指令可用?有时循环可以被向量化,但随后代码无法生成,因为 CPU 不提供向量化循环所需的那些 SIMD 指令。
标签: c++ optimization vectorization sse simd