有没有办法加快对以下表达式的评估?

Boy*_*nov 1 c++ math optimization math.h

我已经分析了我的程序,它花费了20%的CPU时间,基本上评估了以下表达式:

abs(x) > abs(y)
Run Code Online (Sandbox Code Playgroud)

其中x,y是双精度浮点变量.

有没有办法将表达式重构为更快的变体?

以下行(在两个不同的地方调用)在每行占用接近10%的CPU时间:

(这是函数Image_3 :: TestGradientAtPoint的片段)

       if (abs(maxx[ch]) < abs(a)) maxx[ch] = a; 
01187AC9  mov         eax,dword ptr [ch]  
01187ACC  sub         esp,8  
01187ACF  fld         qword ptr [ebp+eax*8-68h]  
01187AD3  fstp        qword ptr [esp]  
01187AD6  call        abs (11305F9h)  
01187ADB  fld         qword ptr [ebp-70h]  
01187ADE  fstp        qword ptr [esp]  
01187AE1  fstp        qword ptr [ebp-0F8h]  
01187AE7  call        abs (11305F9h)  
01187AEC  add         esp,8  
01187AEF  fcomp       qword ptr [ebp-0F8h]  
01187AF5  fnstsw      ax  
01187AF7  test        ah,41h  
01187AFA  jne         Image_3::TestGradientAtPoint+176h (1187B06h)
01187AFC  mov         eax,dword ptr [ch]  
01187AFF  fld         qword ptr [ebp-70h]  
01187B02  fstp        qword ptr [ebp+eax*8-68h]  
Run Code Online (Sandbox Code Playgroud)

分析器声明对abs()的调用占用了20%的CPU时间.我按10 ^ 8次迭代的顺序调用方法 - 我正在使用大图像.

编辑

我忘了说,但是代码是在调试模式下运行的,我需要在这里优化一下,因为我希望仍能在合理的时间内使用MSVC调试器.

SGM*_*GM1 6

这可能不会更快,但如果更快地评估算术表达式:

if ((x - y) * (-x - y) < 0)
    // then abs(x) > abs(y)
Run Code Online (Sandbox Code Playgroud)

我相信这会将表达式的数量固定为3(2算术表达式和比较为零)而不是来自abs方法的3表达式(每个abs检查是否为负,反转符号否则只返回值然后比较每个abs)

编辑:

正如andre所说,你总是可以明确地对浮子进行平方.回想起来更有意义.

if (x * x > y * y)
    // then abs(x) > abs(y)
Run Code Online (Sandbox Code Playgroud)

由于(xy)( - xy)= y ^ 2-x ^ 2

  • 我在考虑建议比较`x*x> y*y`但是如果数字是大的乘法可能会导致溢出. (2认同)

小智 5

告诉编译器进行优化.在GCC或clang中你使用-O2-O3标记 - 后者更具攻击性.在MSVC中,您可以使用/O2/Ox标志(IIRC;我很少使用该编译器).如果没有启用优化,您不能指望100000000次迭代能够快速运行.

如果要在未启用优化的情况下进行调试,但仍在合理的时间范围内,请尝试使用较小的数据集; 或者作为Mysticial提到的,启用优化调试并在调试器中接受随机更改的值和其他神秘的观察.