Nor*_* P. 9 64-bit gcc sse register-allocation avx
我正在尝试为Windows x64目标编写一些计算密集型代码,使用SSE或新的AVX指令,在GCC 4.5.2和4.6.1,MinGW64(TDM GCC构建和一些自定义构建)中进行编译.我的编译器选项是-O3 -mavx.(-m64暗示)
简而言之,我想对4个打包浮点数的3D矢量进行一些冗长的计算.这需要4x3 = 12 xmm或ymm寄存器用于存储,2或3个寄存器用于临时结果.这应该恕我直言,适合64位目标可用的16个SSE(或AVX)寄存器.但是,GCC使用寄存器溢出产生非常不理想的代码,仅使用寄存器xmm0-xmm10并将数据从堆栈中移入和移入堆栈.我的问题是:
有没有办法说服GCC使用所有寄存器xmm0-xmm15?
要修改想法,请考虑以下SSE代码(仅供参考):
void example(vect<__m128> q1, vect<__m128> q2, vect<__m128>& a1, vect<__m128>& a2) {
for (int i=0; i < 10; i++) {
vect<__m128> v = q2 - q1;
a1 += v;
// a2 -= v;
q2 *= _mm_set1_ps(2.);
}
}
Run Code Online (Sandbox Code Playgroud)
这里vect<__m128>只是一个struct 3 __m128,有自然的加法和乘以标量.当行a2 -= v被注释掉时,即我们只需要3x3寄存器进行存储,因为我们忽略了a2,所产生的代码确实很简单,没有移动,所有内容都在寄存器中执行xmm0-xmm10.当我删除注释时a2 -= v,代码非常糟糕,寄存器和堆栈之间有很多混乱.即使编译器可以只使用寄存器xmm11-xmm13或其他东西.
我实际上还没有看到GCC xmm11-xmm15在我的所有代码中的任何地方使用任何寄存器.我究竟做错了什么?我知道它们是被调用者保存的寄存器,但这种开销完全可以通过简化循环代码来证明.
jal*_*alf 13
两点:
所以,如果你想要更好的寄存器分配,你基本上有两个选择:
小智 5
实际上,你看到的不是溢出,它是gcc在内存中的a1和a2上运行,因为它无法知道它们是否有别名.如果将最后两个参数声明为vect<__m128>& __restrict__GCC,则将注册分配a1和a2.
| 归档时间: |
|
| 查看次数: |
6479 次 |
| 最近记录: |