我有一个像这样的内部循环
for(i=0 ;i<n;i++){
x[0] += A[i] * z[0];
x[1] += A[i] * z[1];
x[2] += A[i] * z[2];
x[3] += A[i] * z[3];
}
编译器可以轻松地将内部4条指令转换为SSE指令。当前的编译器会这样做吗?如果他们这样做,我必须做什么来强制编译器这样做?
最佳答案
根据您提供的信息,这无法矢量化,因为指针可能彼此别名,即 x
数组可能与 A
或 重叠>z
.
帮助编译器解决问题的一个简单方法是将x
声明为__restrict
。另一种方法是像这样重写它:
for(i=0 ;i<n;i++)
{
float Ai=A[i];
float z0=z[0], z1=z[1], z2=z[2], z3=z[3];
x[0] += Ai * z0;
x[1] += Ai * z1;
x[2] += Ai * z2;
x[3] += Ai * z3;
}
我从来没有真正尝试过让编译器自动向量化代码,所以我不知道这是否会做到这一点。即使它没有被矢量化,它也应该更快,因为可以更有效地排序加载和存储,并且不会导致加载命中存储。
如果您拥有比编译器更多的信息(例如,您的指针是否是 16 字节对齐的),并且应该能够利用它来发挥您的优势(例如,使用对齐加载)。请注意,我并不是说您应该始终尝试击败编译器,只有当您知道的比编译器多时。
进一步阅读:
- Load-hit-stores and the __restrict keyword
- Memory Optimization (别名从幻灯片 35 左右开始)
关于sse - 如何让 ICC 编译器在内循环中生成 SSE 指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6591291/