Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.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++ 让函数调用在C++;?_C++_Performance_Function Call - Fatal编程技术网

C++ 让函数调用在C++;?

C++ 让函数调用在C++;?,c++,performance,function-call,C++,Performance,Function Call,在我的项目中,我有一个类,其中执行时间是第一个目标。对于它,我不太关心维护、订单等。至少直到昨天我才在乎。。。现在我也有点担心了 我有一个类,比如说a,它对来自照相机的图像执行多次扫描,也就是说,一个可变宽度的窗口实时扫描它们 class A{ // methods and attributes of A: ... void runiterator(){ ... for{ // change window’s di

在我的项目中,我有一个类,其中执行时间是第一个目标。对于它,我不太关心维护、订单等。至少直到昨天我才在乎。。。现在我也有点担心了

我有一个类,比如说a,它对来自照相机的图像执行多次扫描,也就是说,一个可变宽度的窗口实时扫描它们



    class A{  
    // methods and attributes of A:  
    ...  
    void runiterator(){  
      ...  
    for{    // change window’s dimension  
      for{  // rows  
       for{ // columns  
          // many lines of code of operations to be executed for each window at each position  
          ...      
       }  
      }   
     }  
    }  
    }; 

性能显示已经有一点延迟,但我可以跳过图像的有限区域来解决它。此外,我还有第二个函数,比如B,它的方案与a完全相同,在每次扫描时执行不同的操作(幸运的是比a快得多)

好吧,现在是时候加入所有的行动,以显著提高整体结果。只是代码真的会变得一团糟,庞大而且混合了真正不同的东西。我想定义一个类X,它进行迭代,并在每次扫描时执行对a_new中一个函数和B_new中一个函数的函数调用。但我担心每个映像大约200000x2的函数调用会导致性能损失

你有什么建议

编辑
对于只重新调用的类X(因此只能与现在的A进行比较),我从多次重复中得到了平均值:

在一系列56幅图像上执行X的时间=6.15秒
在同一系列56幅图像上执行A的时间=5.98秒

我的嫌疑犯似乎并不那么天真。
差额约为3%,虽然相差不大,但仍为损失感到遗憾

随着_forceinline时间是5.98秒的X,以及,但我宁愿不依赖它

我认为代码已经优化,进一步改进的余地很小。
事实上,它可以在相对较短的时间内对图像进行大量处理。

在A类中,顺序处理数据是不可能的,因为它基于来自不可预测图像的值。这就是为什么B类(能够做到这一点的)速度要快得多的原因。

在担心它之前,您确实必须衡量它是否会导致性能问题

如果有问题,请尝试使用模板。编写函数的两个变体,然后将它们用作进行迭代的函数模板中的函子。您将实例化这两个版本,并调用相应的版本。编译器应该内联调用(但最好验证这一点)


我在医学图像处理中使用了它,效果非常好。

你必须测量效果,因为很难判断编译器到底产生了什么–尤其是在
O3
。当然,如果编译器没有内联函数,则函数调用会产生开销。如果函数可以内联,请尝试向编译器提供
inline
提示

函数调用开销很大程度上取决于您调用的函数类型。在汇编程序级别(假设没有恶意的操作系统页面错误处理),现代英特尔处理器上的
调用地址
指令需要0个周期(对于
jmp地址
指令也是如此)。如果函数地址是从某些数据源计算出来的,例如vtbl查找、对外部DLL的调用(如果使用Win32)或涉及到一个条件,则会引入开销。这些包括访问内存和污染缓存。这就引出了大人物

在等待数据到达CPU时,大多数性能都会丢失。CPU的速度远远大于从RAM读取数据的速度。这就是为什么有几个级别的缓存,每个级别通常都比上一个级别更大、更慢。函数调用的成本,即使是复杂的调用,也比数据读取时丢失缓存所损失的时间要少

这类事情的标题是:微观优化

一般情况下,避免随机数据访问,按顺序处理数据,即先处理项目n,然后再处理项目n+1、n+2等,而不是n、n+100、n+200等、n+1、n+101、n+201等

另外,给编译器内联函数的机会——这样,如果结果产生更快的代码,内联就可以完成(编译器非常清楚什么时候内联是有益的)

还要注意,大函数可能比许多小函数慢(这与CPU缓存本地的UOP缓冲区有关)。对数据进行多次迭代可能比一次性完成所有工作都要快。只有分析代码才能告诉您哪个更快


最后,更好的算法通常是获得更好性能的途径。您的算法是最优的吗?

您可以尝试并测量两个版本吗?我们不能说调用增加了多少开销,因为这是相对的。是的,请测量并给编译器一个内联函数调用的机会。这取决于这些函数的功能。如果以牺牲清晰性为代价将执行时间作为主要目标,则很可能会得到性能糟糕的代码。相反,将清晰性和可维护性作为首要任务。很可能,无论如何,您都会通过这种方式获得最佳性能。除非你比这个问题所暗示的更有经验,否则你对性能的直觉无论如何都是错误的,你的“优化”代码将是脆弱的,因此很难真正优化。(高级算法选择是例外——这适用于低级和中级选择,比如函数边界应该在哪里。)如果算法太慢,尝试优化它!