Cod*_*ard 4 c++ floating-point x86
是什么原因导致第一个数据集的执行时间增加了?装配说明是相同的.
如果DN_FLUSH标志未打开,则第一个数据集需要63毫秒,第二个数据集需要15毫秒.
在DN_FLUSH标志打开的情况下,第一个数据集需要15毫秒,第二个数据集需要约0毫秒.
因此,在这两种情况下,第一数据集的执行时间都要大得多.
有没有办法减少执行时间与第二个数据集更接近?
我正在使用C++ Visual Studio 2005,/ arch:SSE2/fp:在Intel Core 2 Duo T7700 @ 2.4Ghz Windows XP Pro上快速运行.
#define NUMLOOPS 1000000
// Denormal values flushed to zero by hardware on ALPHA and x86
// processors with SSE2 support. Ignored on other x86 platforms
// Setting this decreases execution time from 63 milliseconds to 16 millisecond
// _controlfp(_DN_FLUSH, _MCW_DN);
float denormal = 1.0e-38;
float denormalTwo = 1.0e-39;
float denormalThree = 1;
tickStart = GetTickCount();
// Run First Calculation Loop
for (loops=0; loops < NUMLOOPS; loops++)
{
denormalThree = denormal - denormalTwo;
}
// Get execution time
duration = GetTickCount()-tickStart;
printf("Duration = %dms\n", duration);
float normal = 1.0e-10;
float normalTwo = 1.0e-2;
float normalThree = 1;
tickStart = GetTickCount();
// Run Second Calculation Loop
for (loops=0; loops < NUMLOOPS; loops++)
{
normalThree = normal - normalTwo;
}
// Get execution time
duration = GetTickCount()-tickStart;
printf("Duration = %dms\n", duration);
Run Code Online (Sandbox Code Playgroud)
Ste*_*non 11
引自英特尔优化手册:
当SIMD浮点指令的输入操作数[这里包括使用SSE完成的标量算法]包含的值小于数据类型的可表示范围时,会发生非正规异常.这会导致严重的性能损失.SIMD浮点运算具有清零模式,其中结果不会下溢.因此,后续计算将不会面临处理非正规输入操作数的性能损失.
至于如何避免这种情况,如果你不能刷新非规范:尽你所能确保你的数据适当缩放,你首先不会遇到非正规数.通常这意味着延迟应用一些比例因子,直到你完成所有其他计算.
或者,你的计算中double指数范围要大得多,因此你不太可能首先遇到非正规数.