C++ 自动矢量化不工作

C++ 自动矢量化不工作,c++,optimization,vectorization,sse,simd,C++,Optimization,Vectorization,Sse,Simd,我试图让我的代码自动矢量化,但它不起作用 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;

我试图让我的代码自动矢量化,但它不起作用

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];
    }
}
可以看出,原因“1305”表示“编译器无法识别此循环的适当矢量化类型信息。”我不确定这意味着什么。有什么想法吗

将第二个循环拆分为两个循环后:

for (int i = 0; i < N; i++){
    sumarray[i] = x[i] * y[i];
}

for (int i = 0; i < N; i++){
    sum += sumarray[i];
}
for(int i=0;i

现在,上面的第一个循环矢量化了,但第二个循环没有矢量化,再次出现错误代码1305。

发生错误1305是因为优化器没有矢量化循环,因为没有使用值
sum
。只需添加
printf(“%d\n”,sum)
即可解决此问题。但随后您会得到一个新的错误代码1105“循环包含一个未识别的缩减操作”。要解决此问题,您需要设置

原因是浮点运算是不关联的,使用SIMD或MIMD(即使用多线程)的缩减需要关联。通过使用更宽松的浮点模型,您可以进行缩减

我刚刚用下面的代码对它进行了测试,默认的
fp:precise
不会矢量化,当我使用
fp:fast
时,它会矢量化

#include <stdio.h>
int main() {
    const int N = 4096;
    float x[N];
    float y[N];
    float sum = 0;
    for (int i = 0; i < N; i++){
        sum += x[i] * y[i];
    }
    printf("sum %f\n", sum);
}
#包括
int main(){
常数int N=4096;
浮动x[N];
浮动y[N];
浮点数和=0;
对于(int i=0;i

关于您关于带
rand()
函数的循环的问题,
rand()
函数不是SIMD函数。它不能矢量化。您需要找到一个SIMD rand()函数。我不知道有一个。另一种方法是预先计算一个随机数数组,然后改用该数组。在任何情况下,
rand()
都是一个可怕的随机数,只对一些玩具箱有用。考虑使用Melsern捻线机PRNG. 一个问题可能是堆栈分配不一定由编译器对齐。如果编译器支持c++11,则可以使用:

float x[N] alignas(16);
float y[N] alignas(16);
显式获取16字节对齐内存,这是大多数SSE操作所需的


编辑:


即使对齐不是问题,而且您的编译器正在对未对齐的代码进行矢量化,您也应该进行此优化,因为未对齐的SSE操作与对齐的SSE操作相比非常慢。

您编译的SIMD主机是什么?可能是主机没有提供所需的指令(我怀疑您需要一个水平加法。您是否尝试将循环分成两个:一个生成
sum[]
向量,另一个生成
sum[]中元素的循环
?这至少可以缩小所发生的事情的范围。我不确定您所说的SIMD主机是什么意思。我的CPU是intel core i7。另外,非常抱歉,我错报了第一个循环确实得到矢量化,这是不正确的。我已经更新了帖子和输出消息。谢谢您的建议,现在要尝试打破循环。有必要吗y使其成为一个向量,或者我可以使用一个和数组吗?打破循环并将相关信息添加到问题中。尝试添加“/arch:AVX”到命令行。它应该能够生成额外的SIMD指令。@JonB.Jones:对于SIMD主机,我的意思是,您为哪个CPU生成代码,哪些SIMD指令可用?有时可以对循环进行矢量化,但无法生成代码,因为CPU不提供对循环进行矢量化所需的SIMD指令.所以,为了确保..像这样编译:cl filename.cpp/O2/fp:fast/Qvec report:2?因为这仍然会给我相同的错误代码。@JonB.Jones,你不能用
rand()
函数向量化你的函数,但是如果你使用
fp:fast
你可以向量化减少。我自己测试过。@JonB.Jones,你会得到错误代码1305“没有足够的类型信息”。我得到错误代码1105“循环包含未识别的还原操作“。我不知道为什么我们会得到不同的错误代码。@JonB.Jones,没有
printf
我会得到你的错误代码。当我打印值时,我不会得到错误代码,它会矢量化。显然,如果你不使用该值,优化器不会矢量化循环。尝试添加
printf(“%f\n”,sum)和
fp:fast`。没关系,我并不真的担心rand()函数的循环。至于另一个,添加printf()函数实际上成功了!非常感谢!
float x[N] alignas(16);
float y[N] alignas(16);