浮点数学执行时间

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指数范围要大得多,因此你不太可能首先遇到非正规数.

  • @KennyTM:使用基数2并避免近似:浮动下溢在"2** - 126",双倍在"2** - 1022" (3认同)
  • 顺便说一句,`float`的非正常极限大约是1.18e-38,而'double`的非正常极限大约是2.225e-308. (2认同)