我正在尝试为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
在我的所有代码中的任何地方使用任何寄存器.我究竟做错了什么?我知道它们是被调用者保存的寄存器,但这种开销完全可以通过简化循环代码来证明.
我正在使用基于GCC 4.6.1的MinGW64构建Windows 64bit目标.我正在玩新的英特尔AVX指令.我的命令行参数是-march=corei7-avx -mtune=corei7-avx -mavx
.
但是当我在堆栈上分配局部变量时,我开始遇到分段错误错误.GCC使用对准移动VMOVAPS
和VMOVAPD
移动__m256
和__m256d
周围,并且这些指令需要32字节对齐.但是,Windows 64bit的堆栈只有16字节对齐.
如何将GCC的堆栈对齐更改为32个字节?
我尝试使用-mstackrealign
但无济于事,因为它只对齐16个字节.我也无法__attribute__((force_align_arg_pointer))
工作,无论如何它都会对齐16个字节.我无法找到任何其他可以解决此问题的编译器选项.任何帮助是极大的赞赏.
编辑:
我尝试使用-mpreferred-stack-boundary=5
,但GCC说这个目标不支持5.我没有想法.
愚蠢的问题:如何阻止Windows 7存储崩溃的应用程序的内存转储?
我在C++应用程序中试验堆栈分配,因此玩具程序崩溃了很多.对于每次崩溃,Windows都会将内存转储到%USER%/ AppData/Local/CrashDumps.每个约150MB.如何禁用此功能?我在网上搜索得越来越广.我在Windows 7上唯一能找到的是系统→高级→启动和恢复→系统故障崩溃转储,我已经禁用了这些.
这不是什么大问题,只是烦人,因为它位于我的用户档案中.