我只是通过_mm_setcsr( _mm_getcsr() | 0x40 )
设置此选项,尝试使用SSE选项“denormals is zeros”。
我发现了一个有趣的事情:当两个操作数都是非正规的时,这并不会阻止generating
非正规的SSE!
它只是让SSE将非正规操作数看作是零。
正如我解释的那样,我知道这个选项的作用。 但这个选项有什么用呢?
我刚读过用户核子链接的Intel article。 我很好奇非正规数对SSE计算的性能影响。
所以我写了一个小程序来测试这个:
#include <windows.h>
#include <intrin.h>
#include <iostream>
using namespace std;
union DBL
{
DWORDLONG dwlValue;
double value;
};
int main()
{
DWORDLONG dwlTicks;
DBL d;
double sum;
dwlTicks = __rdtsc();
for( d.dwlValue = 0, sum = 0.0; d.dwlValue < 100000000; d.dwlValue++ )
sum += d.value;
dwlTicks = __rdtsc() - dwlTicks;
cout << sum << endl;
cout << dwlTicks / 100000000.0 << endl;
dwlTicks = __rdtsc();
for( d.dwlValue = 0x0010000000000000u, sum = 0.0;
d.dwlValue < (0x0010000000000000u + 100000000); d.dwlValue++ )
sum += d.value;
dwlTicks = __rdtsc() - dwlTicks;
cout << sum << endl;
cout << dwlTicks / 100000000.0 << endl;
return 0;
}
(我打印的总和只是为了防止编译器优化掉总和。)
结果是在我的Xeon E3-1240(Skylake)上,当“d”非正常时,每次迭代需要四个时钟周期。当“d”是非正规时,每次迭代大约需要150个时钟周期!如果我没有看到相反的情况,我永远不会相信非正规会产生如此巨大的性能影响。