我试图通过打开/ arch:AVX2来获取特定软件的更快二进制文件,因为我在应该支持该指令集的CPU上运行它(i7 4770和i7 4800MQ)。
但是,这样做会产生一个可执行文件,它会随着消息“#34; xxx.exe已停止工作而崩溃”,就像我在非AVX2硬件上运行它一样。
我知道运行y-cruncher可以在我的系统上正确支持AVX2,它会检测AVX2硬件并运行相应的可执行文件。
如果我指定/ arch:AVX,则会出现同样的问题
在没有/ arch选项的情况下构建时代码正常运行。其他使用的构建选项是:
/Ox /Ob2 /Oi /Oy /GT /GL /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /GR /openmp /Gd /TP /GL /GF /Ot /Qfast_transcendentals
该软件本身并未使用特定的AVX2内在函数,因为它旨在在更广泛的平台上运行。我只是想在我的平台上获得更好的性能,而无需更改代码(我甚至无法做到这一点,因为这是一个复杂的软件,我根本不是专家程序员)。
我的问题是:为什么该选项会使程序在启用AVX2的计算机上崩溃?我错过了阻止/拱起的东西:AVX2正常工作,例如与其他旗帜不兼容? (我检查了MS文档,没有找到任何"交叉依赖"与AVX2相关)。
编辑:我在这里添加了一些关于代码的更多信息,正如Regis Portalez所建议的那样。 以下是导致问题的代码段。 VS调试器在指示访问冲突的最后一行之前停止:
void Film::ComputeGroupScale(u_int i)
{
const Color white(space.ToXYZ(RGB(1.f)));
if (groups[i].temperature > 0.f) {
Color colorTemp(SPD(groups[i].temperature));
colorTemp /= colorTemp.Y();
groups[i].convert = Adapter(white,
space.ToXYZ(groups[i].rgbScale)) *
Adapter(white, colorTemp);
} else {
groups[i].convert = Adapter(white,
space.ToXYZ(groups[i].rgbScale));
}
groups[i].convert *= groups[i].globalScale;
}
以下是最后一行的汇编代码:
}
groups[i].convert *= groups[i].globalScale;
00007FFB28E43B2A vbroadcastss ymm2,dword ptr [rax+rbx+40h]
00007FFB28E43B31 mov rax,qword ptr [rdi+1B8h]
00007FFB28E43B38 vmulps ymm0,ymm2,ymmword ptr [rax+rbx+54h]
00007FFB28E43B3E vmovups ymmword ptr [rax+rbx+54h],ymm0
00007FFB28E43B44 vmulss xmm0,xmm2,dword ptr [rax+rbx+74h]
00007FFB28E43B4A vmovss dword ptr [rax+rbx+74h],xmm0
00007FFB28E43B50 vzeroupper
}
调试器指示访问冲突发生在 vbroadcastss 。寄存器内容如下所示,表示尝试读取位置0:
RAX = 000000003F800000 RBX = 0000000000000000 RCX = 000007FEDC1143A8 RDX = 000000000021B6E8
RSI = 0000000007709710 RDI = 0000000002D165E0 R8 = 000000000021B6B0 R9 = 0000000004D25190
R10 = 00000000003B0274 R11 = 000000000021B428 R12 = 0000000000000001 R13 = 0000000000000000
R14 = 0000000000000000 R15 = 0000000002288480 RIP = 000007FEDBDC2C0A RSP = 000000000021B690
RBP = 000000000021B790 EFL = 00010340
0x000000003f800040 = 00000000
作为比较,当/ arch:未使用AVX2时,这是程序集:
groups[i].convert *= groups[i].globalScale;
000007FEDCA019E8 movups xmm0,xmmword ptr [rax+rbx+54h]
000007FEDCA019ED shufps xmm2,xmm2,0
000007FEDCA019F1 mulps xmm0,xmm2
000007FEDCA019F4 movups xmmword ptr [rax+rbx+54h],xmm0
000007FEDCA019F9 movups xmm0,xmmword ptr [rax+rbx+64h]
000007FEDCA019FE mulps xmm0,xmm2
000007FEDCA01A01 movups xmmword ptr [rax+rbx+64h],xmm0
000007FEDCA01A06 mulss xmm2,dword ptr [rax+rbx+74h]
000007FEDCA01A0C movss dword ptr [rax+rbx+74h],xmm2
}
访问冲突中涉及的 groups 对象定义为:
std::vector<Group> groups;
class Group {
public:
Group(const string &n) : samples(0.f), name(n),
globalScale(1.f), temperature(0.f),
rgbScale(1.f), convert(Color(1.f), Color(1.f)),
enable(true) { }
~Group() {
for(vector<Buffer *>::iterator buffer = buffers.begin(); buffer != buffers.end(); ++buffer)
delete *buffer;
}
void CreateBuffers(const vector<BufferConfig> &configs, u_int x, u_int y);
Buffer *getBuffer(u_int index) const {
return buffers[index];
}
double samples;
vector<Buffer *> buffers;
string name;
float globalScale, temperature;
RGB rgbScale;
Adapter convert;
bool enable;
};
我希望此信息可以进行更多分析...