0

在我的项目中,我有一个以执行时间为首要目标的课程。对于它我不太关心维护,订单等。至少我直到昨天才在意……现在我也不得不有点担心了。

我有一个类,比如 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 的函数调用会导致性能损失。

你有什么建议?

编辑
对于只调用 Anew 的 X 类(所以它只能与现在的 A 进行比较),平均而言,我得到了多次重复:

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

看来我的嫌疑人并没有那么天真。
差价大约是3%,不算多,但还是对损失感到抱歉。

X 的 __forceinline 时间也是 5.98 秒,但我不想依赖它。

我认为代码已经过优化,进一步改进的余地很小。
事实上,它在相对较短的时间内对图像做了很多事情。
在 A 类中顺序处理数据是不可能的,因为它基于来自无法预测的图像的值。这就是为什么 B 级(设法做到这一点)要快得多的原因。

4

3 回答 3

1

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

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

我将它用于医学图像处理,它就像一个魅力。

于 2012-10-10T11:57:13.477 回答
1

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

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

这类事情属于标题:微优化。

通常,避免随机数据访问,按顺序处理数据,即执行第 n 项,然后执行 n+1、n+2 等而不是 n、n+100、n+200 等,n+1、n+101、n +201 等

此外,让编译器有机会内联函数 - 如果结果产生更快的代码,则内联将完成(并且编译器非常清楚何时这样做是有益的)。

Also note that big functions can be slower than lots of small functions (it's to do with the buffer of uops the CPU caches locally). Iterating over the data several times might be quicker than doing everything in one go. Only profiling the code will tell you which one is quicker.

Finally, a better algorithm is usually the way to better performance. Is your algorithm optimal?

于 2012-10-10T12:11:57.197 回答
0

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

于 2012-10-10T11:58:44.703 回答