如何分离C++;不影响性能的代码? 我重构C++代码遇到了麻烦。代码本身只有200行,即使是作为一个图像处理事务,它也会循环很多次,我遇到的障碍(我想)涉及到非常棘手的细节(例如内存访问)

如何分离C++;不影响性能的代码? 我重构C++代码遇到了麻烦。代码本身只有200行,即使是作为一个图像处理事务,它也会循环很多次,我遇到的障碍(我想)涉及到非常棘手的细节(例如内存访问),c++,image-processing,refactoring,compiler-optimization,C++,Image Processing,Refactoring,Compiler Optimization,该程序生成正确的输出,但最终应该是实时运行的。最初,每320x240px帧大约需要3分钟,但现在大约需要2秒(在中端工作站和低端笔记本电脑硬件上运行速度大致相同)。然而,与每秒24次相比,仍然相差甚远。基本上,我所做的任何改变都会通过数百万次的重复传播,随着我接近实时标记,跟踪我的初学者错误变得越来越麻烦 在2点处,程序计算欧几里德距离的一个计算成本较低的变量,称为出租车距离(绝对差之和) 现在,简略的版本: std::向量正视图,正视图; /*循环像素,读取值*/ 距离=(abs(pValue

该程序生成正确的输出,但最终应该是实时运行的。最初,每320x240px帧大约需要3分钟,但现在大约需要2秒(在中端工作站和低端笔记本电脑硬件上运行速度大致相同)。然而,与每秒24次相比,仍然相差甚远。基本上,我所做的任何改变都会通过数百万次的重复传播,随着我接近实时标记,跟踪我的初学者错误变得越来越麻烦

在2点处,程序计算欧几里德距离的一个计算成本较低的变量,称为出租车距离(绝对差之和)

现在,简略的版本:

std::向量正视图,正视图;
/*循环像素,读取值*/
距离=(abs(pValues[0]-qValues[0])+abs(pValues[1]-qValues[1])+abs(pValues[2]-qValues[2]);
如果(距离<阈值)
{
正向。向后推(世界其他地区);
正电荷。推回(col);
}
如果我包装功能,如下所示:

inttaxicab_dist(intlp,
国际美联社,
国际石油公司,
int Lq,
int aq,
int bq)
{
收益率(abs(Lp-Lq)+abs(ap-aq)+abs(bp-bq));
}
并从同一个.cpp文件中调用它,不会降低性能。如果我在单独的.hpp/.cpp文件中声明并定义它,,我会得到一个显著的减速。这与我在本科课程中听到的直接相反(“包括一个文件就等于复制粘贴它”)。我最接近原始代码的性能是通过声明参数const,但它仍然需要大约100毫秒的时间,我的判断是,对于这样一个微不足道的任务来说,这是无法承受的。再说一次,如果我也使它们const int&,我不明白为什么速度会减慢(显著)。然后,当我做了最明智的事情,并选择将数组作为参数时,我再次受到性能的影响。我甚至不敢尝试任何模板化的恶作剧,或者尝试让函数修改其行为,使其接受任意数量的对,至少在我了解我自己之前是这样

所以我的问题是:如何将计算定义保存到单独的文件中,并使其执行与原始解决方案相同的操作?此外,编译器是否将我的程序优化为<强>运行2秒而不是15 < /强>是<强>大红旗< /强>(坏的算法设计,不使用更奇异的C++关键词/特征)?< /P> 我猜我找不到答案的主要原因是因为我不知道这些东西的名字。我在HPC社区听到过很多关于“矢量化”的说法。这和那有关系吗


如果它在任何方面都有帮助,那么可以找到完整的代码。

正如Joachim Pileborg所说的,您应该首先进行概要分析。找出程序中大部分执行时间发生在哪里。这是您应该优化的地方

在向量中保留空间
向量开始很小,然后根据需要重新分配。这涉及到在内存中分配更大的空间,然后将旧元素复制到新向量。最后释放内存。
std::vector
具有在构建时保留空间的能力。对于大尺寸的向量,这可以节省时间,消除许多重新分配

使用速度优化进行编译
对于现代编译器,您应该设置高速优化,看看它们能做些什么。编译器编写人员有很多窍门,他们经常可以发现您或我错过的优化位置

真理是汇编语言
您需要查看汇编语言列表。如果汇编语言在您认为是瓶颈的区域仅显示两条指令,那么您真的无法加快速度

循环展开
通过多次在
for
循环中复制内容,您可能可以获得更高的性能。这称为循环展开。在某些处理器中,分支或跳转指令比数据处理指令花费更多的执行时间。展开循环可以减少执行的分支指令数。同样,当您提高优化级别时,编译器可能会自动执行此操作

数据缓存优化
在web上搜索“数据缓存优化”。加载和卸载数据缓存会浪费时间。如果您的数据可以放入处理器的数据缓存,则不必一直加载卸载(称为缓存未命中)。还要记住,在执行其他操作之前,在一个位置对数据执行所有操作。这降低了处理器重新加载缓存的可能性

多处理器计算
如果您的平台有多个处理器,例如图形处理单元(GPU),则可以将某些任务委派给它。请注意,通过与其他处理器通信,您也增加了时间。因此,对于小任务,通信开销可能会浪费您通过授权获得的时间

并行计算
与多处理器类似,您可以让操作系统委派任务。操作系统可以委托给处理器中的不同内核(如果有多核处理器),或者在另一个线程中运行。还有一个成本:管理的开销