Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 函数开销能否将程序的速度降低50倍?_C++_Overhead - Fatal编程技术网

C++ 函数开销能否将程序的速度降低50倍?

C++ 函数开销能否将程序的速度降低50倍?,c++,overhead,C++,Overhead,我有一个为项目运行的代码。它是O(N^2),在我的例子中,N是200。有一种算法可以将这个O(N^2)转换为O(N logN)。这意味着,使用这种新算法,速度应该快约100倍。然而,我只得到了2倍的增长系数(也就是快2倍) 我试图缩小范围,看看我是否把事情弄糟了,或者这是否是我编写这个程序的固有方式。首先,我在嵌套类中有很多函数开销。例如,我有很多(在许多循环中): 因为当涉及到实际数据时,我得到了正确的结果,仅仅是错误的速度增加,我想知道函数开销是否会导致速度降低50倍 谢谢 绝对最大的影响是

我有一个为项目运行的代码。它是O(N^2),在我的例子中,N是200。有一种算法可以将这个O(N^2)转换为O(N logN)。这意味着,使用这种新算法,速度应该快约100倍。然而,我只得到了2倍的增长系数(也就是快2倍)

我试图缩小范围,看看我是否把事情弄糟了,或者这是否是我编写这个程序的固有方式。首先,我在嵌套类中有很多函数开销。例如,我有很多(在许多循环中):

因为当涉及到实际数据时,我得到了正确的结果,仅仅是错误的速度增加,我想知道函数开销是否会导致速度降低50倍


谢谢

绝对最大的影响是缓存未命中。一级缓存未命中的成本相对较低,但当您在二级缓存(或三级缓存,如果您有)上未命中时,可能会损失数百甚至数千个周期到传入暂停

问题是,这可能只是问题的一部分。在分析代码之前,不要优化代码。找出慢的区域,然后找出它们慢的原因。一旦你理解了为什么它运行缓慢,你就有机会对它进行优化


顺便说一句,O表示法非常方便,但不是全部和全部。我已经看到O(n^2)算法对于少量数据(小的可能意味着不到几千)的工作速度明显快于O(n logN),因为它们的缓存效率要高得多。

首先,您对
O(n logN)
O(n^2)
对于
n=200
的解释是错误的。大Oh表示法处理上限和极限行为,不考虑复杂性中的任何乘法常数


其次,是的,在现代硬件上,由于管道中断,函数调用往往相对昂贵。要了解在您的情况下这是一个多大的因素,您必须拿出一些微基准。

关于大O表示法的重要一点是,它只指定执行时间的限制,随着数据集大小的增加,任何常量都会被丢弃。虽然O(N^2)确实比O(N logn)慢,但实际运行时间可能是N^2而不是1000N logn,也就是说,在某些数据集上,O(N^2)可能比O(N logn)快


如果没有更多的细节,很难说得更多-是的,函数调用确实有相当大的开销,这可能就是为什么您没有看到性能有更大的提高-或者可能只是您的O(N log N)在您这样大小的数据集上表现不太好。

我研究过图像处理算法,而调用每像素函数(即640x480将是307200)会显著降低性能。尝试将函数声明为内联函数,或将函数设置为宏。这可以快速显示是否是因为函数调用。尝试查看一些分析工具。VS2010附带了一些不错的工具,或者还有英特尔VTune、glowcode。它们可以帮助你显示你在哪里花费时间


我不认为1600个函数调用会大大降低性能(200个log 200)

我建议使用

有关评测的主要常见问题解答主题如下:

  • gprof
    (需要编译时检测)
  • valgrind--tool=callgrind
    kcachegrind
    ;出色的工具和出色的可视化效果-屏幕截图如下:


试着在探查器下运行这两种方法,看看每种方法都花费了多少时间。Big-O表示法显示的是某种东西是如何伸缩的,而不一定是它的性能。对于较小的N值,您可能根本看不到任何差异。“它是O(N^2),在我的例子中,N是200”。给你。你没有正确使用大Oh符号。如果“你的情况下N是200”,那么它就是O(1)。首先,我很抱歉将性能与Big-O表示法混淆。第二,@Mankarse:你会推荐一个剖析器吗?第三,我真的希望这不是函数开销,否则我将不得不把所有的东西都塞进一个,使它非常丑陋,非常有效-intensive@Amit:在OSX上,我喜欢使用内置在活动监视器中的探查器(这是我唯一广泛使用的探查器)。在windows上,我已经取得了很好的效果。我没有在其他系统上做过太多的评测,但是我想了解更多的建议。这真的很有趣。我没有意识到这一点!是否有可能的编译标志可以在某种程度上减少函数开销?我目前正在使用-O3编译,并使用英特尔的icpccompiler@Amit:我所知道的减少函数开销的唯一方法是完全通过内联避免函数开销,这确实会产生巨大的影响。再说一次,没有更多的细节是不可能知道的;因此,如有必要,请通过分析器运行它。@Amit:vTune可能是英特尔x86芯片的最佳配置,但并不便宜。然而,30天的免费试用相当便宜;)
energy = globals->pair_style->LJ->energy();