浮点数学执行时间

时间:2010-01-12 18:56:28

标签: 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);

2 个答案:

答案 0 :(得分:11)

引自英特尔优化手册:

  

当SIMD的输入操作数时   浮点指令[这里包括使用SSE完成的标量算法]包含   小于的值   可表示的数据类型范围,   发生非正规异常。这个   导致显着的表现   罚款。一个SIMD浮点   操作中有一个清零模式   哪个结果不会下溢。   因此后续计算将   不要面对表现的惩罚   处理非正规输入操作数。

至于如何避免这种情况,如果你不能刷新非规范:尽你所能确保你的数据适当缩放,你首先不会遇到非正规数。通常这意味着延迟应用一些比例因子,直到你完成所有其他计算。

或者,在具有更大指数范围的double中进行计算,因此首先会遇到非正规数的可能性要小得多。

答案 1 :(得分:2)

英特尔手册第1卷第10.2.3.3章的另一个引用:

从零到零模式与IEEE标准754不兼容.IEM强制要求 对下溢的掩盖响应是提供非规范化结果(参见 第4.8.3.2节“归一化和非规范化有限数”)。冲到零 模式主要是出于性能原因。以微小的精度为代价 对于下溢很常见的应用程序,可以实现丢失,更快的执行 并且可以容忍将下溢结果舍入为零。