功能大小与执行速度

时间:2012-06-12 15:16:17

标签: c++ multithreading performance function

我记得因为代码大小,CPU缓存或类似的东西而听到“大型函数可能具有更高执行时间”的地方。

如何确定功能大小是否会对我的应用程序造成性能影响?我怎样才能对此进行优化?我有一个CPU密集型计算,我已经拆分(与CPU核心一样多的线程)。主线程等待所有工作线程完成后再继续。

我碰巧在Visual Studio 2010上使用C ++,但我不确定这是非常重要的。

编辑:

我正在运行一个光线追踪器,每像素拍摄约5,000条光线。我创建(cores-1)线程(每个额外核心1个),将屏幕分成行,并将每一行分配给CPU线程。我在每个线程上运行trace函数,每个像素大约5000次。

我实际上正在寻找提高速度的方法。 我可以通过重构减少主跟踪功能的大小,我想知道我是否应该看到性能提升。

很多人似乎在回答错误的问题,我正在寻找这个特定问题的答案,即使你认为我可以通过优化内容来做得更好函数,我想知道是否函数大小/性能关系。

4 个答案:

答案 0 :(得分:5)

这不是函数的大小,它是运行时缓存的代码的总大小。你不会通过将代码分成更多的小函数来加快速度,除非在关键代码路径中根本没有调用其中的某些函数,因此不需要占用任何缓存。此外,如果编译器决定内联它们,那么任何将代码拆分成多个函数的尝试都可能会被反转。

因此,无法确定您当前的代码是否“会对性能造成影响”。与您可以以不同方式构建代码的众多方式中的哪一种相比,这一点与之相比?你不能合理地期望这种变化能够对绩效产生任何特别的影响。

我想你正在寻找的是很少执行的指令(你的探查器会告诉你它们是什么),但是它们位于执行很多的指令附近(因此需要是在缓存中很多,并将拉入它们周围的缓存行)。如果您可以将常用代码集中在一起,那么您将从指令缓存中获得更多。

实际上,这不是一个非常富有成效的优化路线。你不太可能会有太大的不同。如果不出意外,你常用的代码可能已经很小并且已经相邻了,它会在某个地方出现少量的紧密循环(你的探查器会告诉你在哪里)。最低级别的缓存行通常很小(大约32或64字节),因此您需要对代码进行一些非常精细的重新排列。 C ++在你和目标代码之间施加了很多,这妨碍了在内存中小心地放置指令。

perf这样的工具可以为您提供有关缓存未命中的信息 - 其中大部分都不是可执行代码,但在大多数系统上,您要避免哪些缓存未命中并不重要:如果可以避免一些,然后你会加快你的代码。也许不是很多,除非是很多的失误,而是一些。

无论如何,你听到了什么背景?我听到它最常见的一个问题是函数内联有时会适得其反,因为有时代码膨胀的开销大于避免的函数调用开销。我不确定,但是如果你的编译器支持它,那么配置文件引导的优化可能会有所帮助。一个相当合理的配置文件引导优化是优先内联执行大量执行的调用站点,使更冷的代码更小,首先加载和修复的开销更少,并且(希望)对指令的破坏性更小当它被拉入时缓存。对编译器的了解远远超过我的人,会想到这是否是良好的配置文件引导优化,因此决定是否实现它。

答案 1 :(得分:3)

除非您要手动调整到程序集级别,要在缓存中包含特定的代码行,否则您不会在一个大函数和多个小函数之间看到显着的执行差异。在这两种情况下,您仍然需要执行相同数量的工作,这将成为您的瓶颈。

然而,将事情分解为多个较小的功能将更容易维护和更容易阅读 - 尤其是6个月之后,当您忘记了首先做的事情时。

答案 2 :(得分:0)

功能大小不太可能成为您应用程序的瓶颈。你在函数中做的事情就是它的物理尺寸更重要。你的编译器可以用小函数做一些事情,它不能用大函数(即内联),但通常这不是一个巨大的差异。

您可以分析代码以查看真正的瓶颈所在。我怀疑调用一个大函数不是问题。

但是,出于代码可读性的原因,您应该将函数分解为更小的函数。

答案 3 :(得分:-1)

这不是关于功能大小,而是关于你在做什么。根据您的工作,可能会有一些方法来优化它。