我大声尖叫。 这真的让你想知道。
我不敢想象如果我选择“优先考虑尺寸而不是速度”会发生什么。
设置:Visual Studio 2010
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
怎么样:
for (i = 0; i < some_num; i++)
{
one += buf[i] * buf[i];
two += buf[i] * buf[off+i];
}
翻译成这样:
131: for (i = 0; i < some_num; i++)
132: {
133: one += buf[i] * buf[i];
00404B40 movss xmm0,dword ptr [eax-4]
00404B45 movss xmm7,dword ptr [esp+18h]
00404B4B movss xmm2,dword ptr [eax]
00404B4F cvtps2pd xmm3,xmm2
00404B52 movss xmm4,dword ptr [eax+4]
00404B57 cvtps2pd xmm1,xmm0
00404B5A mulsd xmm3,xmm3
00404B5E movss xmm6,dword ptr [eax+8]
00404B63 mulsd xmm1,xmm1
00404B67 cvtps2pd xmm5,xmm4
00404B6A mulsd xmm5,xmm5
00404B6E cvtps2pd xmm7,xmm7
00404B71 addsd xmm1,xmm7
00404B75 cvtpd2ps xmm1,xmm1
00404B79 cvtss2sd xmm1,xmm1
00404B7D addsd xmm1,xmm3
00404B81 xorps xmm3,xmm3
00404B84 cvtpd2ps xmm1,xmm1
00404B88 cvtss2sd xmm1,xmm1
00404B8C addsd xmm1,xmm5
00404B90 cvtpd2ps xmm1,xmm1
00404B94 cvtss2sd xmm3,xmm1
134: two += buf[i] * buf[off+i];
00404B98 cvtps2pd xmm0,xmm0
00404B9B cvtps2pd xmm2,xmm2
00404B9E cvtps2pd xmm1,xmm6
00404BA1 mulsd xmm1,xmm1
00404BA5 addsd xmm3,xmm1
00404BA9 xorps xmm1,xmm1
00404BAC cvtpd2ps xmm1,xmm3
00404BB0 cvtps2pd xmm5,xmm1
00404BB3 movss xmm1,dword ptr [eax+0Ch]
00404BB8 cvtps2pd xmm3,xmm1
00404BBB mulsd xmm3,xmm3
00404BBF addsd xmm5,xmm3
00404BC3 xorps xmm3,xmm3
00404BC6 cvtpd2ps xmm3,xmm5
00404BCA cvtps2pd xmm5,xmm3
00404BCD movss xmm3,dword ptr [eax+10h]
00404BD2 cvtps2pd xmm3,xmm3
00404BD5 mulsd xmm3,xmm3
00404BD9 addsd xmm5,xmm3
00404BDD xorps xmm3,xmm3
00404BE0 cvtpd2ps xmm3,xmm5
00404BE4 cvtps2pd xmm5,xmm3
00404BE7 movss xmm3,dword ptr [eax+14h]
00404BEC cvtps2pd xmm3,xmm3
00404BEF mulsd xmm3,xmm3
00404BF3 addsd xmm5,xmm3
00404BF7 xorps xmm3,xmm3
00404BFA cvtpd2ps xmm3,xmm5
00404BFE cvtps2pd xmm5,xmm3
00404C01 movss xmm3,dword ptr [eax+18h]
00404C06 cvtps2pd xmm3,xmm3
00404C09 mulsd xmm3,xmm3
00404C0D addsd xmm5,xmm3
00404C11 xorps xmm3,xmm3
00404C14 cvtpd2ps xmm3,xmm5
00404C18 movss dword ptr [esp+18h],xmm3
00404C1E movss xmm3,dword ptr [ecx-4]
00404C23 cvtps2pd xmm3,xmm3
00404C26 mulsd xmm3,xmm0
00404C2A movss xmm0,dword ptr [esp+10h]
00404C30 cvtps2pd xmm0,xmm0
00404C33 addsd xmm3,xmm0
00404C37 xorps xmm0,xmm0
00404C3A cvtpd2ps xmm0,xmm3
00404C3E movss xmm3,dword ptr [ecx]
00404C42 cvtps2pd xmm0,xmm0
00404C45 cvtps2pd xmm3,xmm3
00404C48 mulsd xmm2,xmm3
00404C4C addsd xmm0,xmm2
00404C50 movss xmm2,dword ptr [ecx+4]
00404C55 cvtpd2ps xmm0,xmm0
00404C59 cvtss2sd xmm0,xmm0
00404C5D cvtps2pd xmm2,xmm2
00404C60 cvtps2pd xmm3,xmm4
00404C63 mulsd xmm2,xmm3
00404C67 addsd xmm0,xmm2
00404C6B movss xmm2,dword ptr [ecx+8]
00404C70 cvtpd2ps xmm0,xmm0
00404C74 cvtss2sd xmm0,xmm0
00404C78 cvtps2pd xmm2,xmm2
00404C7B cvtps2pd xmm1,xmm1
00404C7E cvtps2pd xmm3,xmm6
00404C81 mulsd xmm2,xmm3
00404C85 addsd xmm0,xmm2
00404C89 movss xmm2,dword ptr [ecx+0Ch]
00404C8E cvtpd2ps xmm0,xmm0
00404C92 cvtss2sd xmm0,xmm0
00404C96 cvtps2pd xmm2,xmm2
00404C99 mulsd xmm2,xmm1
00404C9D addsd xmm0,xmm2
00404CA1 cvtpd2ps xmm0,xmm0
00404CA5 xorps xmm1,xmm1
00404CA8 cvtss2sd xmm1,xmm0
00404CAC movss xmm0,dword ptr [ecx+10h]
00404CB1 cvtps2pd xmm2,xmm0
00404CB4 movss xmm0,dword ptr [eax+10h]
00404CB9 cvtps2pd xmm0,xmm0
00404CBC mulsd xmm2,xmm0
00404CC0 addsd xmm1,xmm2
00404CC4 xorps xmm0,xmm0
00404CC7 cvtpd2ps xmm0,xmm1
00404CCB add eax,20h
00404CCE add ecx,20h
00404CD1 cvtps2pd xmm1,xmm0
00404CD4 movss xmm0,dword ptr [ecx-0Ch]
00404CD9 cvtps2pd xmm2,xmm0
00404CDC movss xmm0,dword ptr [eax-0Ch]
00404CE1 cvtps2pd xmm0,xmm0
00404CE4 mulsd xmm2,xmm0
00404CE8 addsd xmm1,xmm2
00404CEC xorps xmm0,xmm0
00404CEF cvtpd2ps xmm0,xmm1
00404CF3 xorps xmm1,xmm1
00404CF6 cvtps2pd xmm1,xmm0
00404CF9 movss xmm0,dword ptr [ecx-8]
00404CFE xorps xmm2,xmm2
00404D01 cvtps2pd xmm2,xmm0
00404D04 movss xmm0,dword ptr [eax-8]
00404D09 cvtps2pd xmm0,xmm0
00404D0C mulsd xmm2,xmm0
00404D10 addsd xmm1,xmm2
00404D14 xorps xmm0,xmm0
00404D17 cvtpd2ps xmm0,xmm1
00404D1B movss dword ptr [esp+10h],xmm0
00404D21 cmp eax,offset buf+84h (42D6A4h)
00404D26 jl gem+290h (404B40h)
135: }
答案是肯定的。 Visual Studio 目前不支持代码矢量化。如果您查看程序集,就会发现这些都是标量 SSE 指令。而且你的循环显然是可矢量化的。
您将必须使用矢量化编译器才能获得更好的结果。或者使用内在函数自行发出向量 SSE 指令。
您可以尝试的另一件事是:
将浮点模式更改为“快速”而不是“精确”。编译器将中间体提升为双精度并将它们转换回来 - 这增加了很多开销。
看起来您在表达式中混合了单精度和双精度类型,这会导致大量不必要的转换。如果你解决这个问题,那么代码应该更小、更高效。
您也可以使用更好的编译器,例如英特尔的 ICC,它很可能能够矢量化此循环,正如 @Mysticial 已经建议的那样。
还有一点 - 我没有太仔细地研究代码,但看起来循环已经展开,所以实际上它可能比最初看起来更有效。
注意这一点:
00404CCB add eax,20h
00404CCE add ecx,20h
循环已展开,可一次处理 8 个
i
值。