C++ 有没有办法加快下列表达式的计算速度?
我已经分析了我的程序,它花费了20%的CPU时间来计算以下表达式:C++ 有没有办法加快下列表达式的计算速度?,c++,math,optimization,math.h,C++,Math,Optimization,Math.h,我已经分析了我的程序,它花费了20%的CPU时间来计算以下表达式: abs(x) > abs(y) 其中x,y是双精度浮点变量 有没有办法将表达式重构为更快的变体 以下行(在两个不同的位置调用)在每行占用将近10%的CPU时间: (这是函数Image_3::TestGradientAttPoint的一个片段) if(abs(maxx[ch])abs(y)的逻辑替换 x>=0? y>=0&&x>y: y首先要检查的是您实际上正在启用优化。如果没有,可能是编译器没有内联调用,导致了足够的开销
abs(x) > abs(y)
其中x,y是双精度浮点变量
有没有办法将表达式重构为更快的变体
以下行(在两个不同的位置调用)在每行占用将近10%的CPU时间:
(这是函数Image_3::TestGradientAttPoint的一个片段)
if(abs(maxx[ch])
探查器声明对abs()的调用占用了20%的CPU时间。
我正在以10^8次迭代的顺序调用该方法-我正在处理大型图像
编辑
我忘了说,但是代码是在调试模式下运行的,我需要在这里对它进行一些优化,因为我希望仍然能够在合理的时间内使用MSVC调试器。好吧,如果
maxx[]
的顺序不重要,您可以对它进行排序,我认为它会更快
另一件事是,如果“a”对所有maxx[]
都是一样的,那么你可以做a=abs(a)代码>然后直接与a进行比较
我需要看到更多的代码来帮助您 这可能不会更快,但另一个逻辑版本是:
// logical replacement for abs(x) > abs(y)
x >= 0 ?
y >= 0 && x > y :
y <= 0 && x < y ;
//abs(x)>abs(y)的逻辑替换
x>=0?
y>=0&&x>y:
y首先要检查的是您实际上正在启用优化。如果没有,可能是编译器没有内联调用,导致了足够的开销,您会注意到这一点
如果像我怀疑的那样,你真的启用了优化,你将不得不采取一种算法方法。我想不出你能做什么来让它更快
所以你需要考虑类似的事情:
- 您是否关心原始的负数,或者您是否可以对数据进行预过滤,以
abs
ify它
- 你在乎订单吗?你能对数据进行排序以改进算法吗
- 您是否在循环中多次计算一个不变值的
abs
告诉编译器进行优化。在GCC或clang中,您可以使用-O2
或-O3
标记来执行此操作,后者更具攻击性。在MSVC中,您可以使用/O2
或/Ox
标志(IIRC;我很少使用该编译器)。如果不启用优化,就不能期望100000000次迭代快速运行
如果您想在不启用优化的情况下进行调试,但仍在合理的时间范围内,请尝试使用较小的数据集;或者,如Mystical所述,在启用优化的情况下进行调试,并在调试器中接受随机更改的值和其他神秘的观察值。这可能不会更快,但如果算术表达式的计算速度更快:
if ((x - y) * (-x - y) < 0)
// then abs(x) > abs(y)
由于(x-y)(-x-y)=y^2-x^2您可能希望围绕此语句发布代码,因为我怀疑这是真正的问题。您每秒要执行多少个操作?在未启用优化的情况下测量性能…叹气。@perfanoff如果这是调试模式,请忘记它。。。我只能说通过优化来学习调试。@perkanoff-在调试模式下运行告诉编译器“请不要试图让它快速运行”。这就是您得到的。谢谢,这是一个很好的答案,但不幸的是maxx[]的顺序无法更改。您是对的,对abs()的调用不是内联的。我将检查是否以及如何内联它,而不必添加会干扰程序其余部分的编译器优化。感谢您对这种情况的看法。我将测试它并让您知道。很有趣。。。我想你可能在某个地方看到了一个标志。如果两者都是正数和x>y
,则计算结果为负数,即false
。我想建议比较x*x>y*y
,但如果数字较大,则乘法可能会导致溢出。刚刚编辑的表达式的混合符号+1,我认为它现在可以工作了。漂亮的小把戏。:)abs
对于所有数字类型都是重载的。@我理解JamesKanze,但是可能有fabs
的优化,使浮点类型的速度更快。我不知道是哪种方式-我只是指出它作为一种替代。似乎fabs
与abs
的过载有任何不同。事实上,因为重载是纯C++,其中“<代码> Fabs <代码>是C,所以有一种明显的可能性,即重载是代码>内联< /COD>,而<代码> Fabs<代码>不是。
if ((x - y) * (-x - y) < 0)
// then abs(x) > abs(y)
if (x * x > y * y)
// then abs(x) > abs(y)