函数大小与执行速度

Posted

技术标签:

【中文标题】函数大小与执行速度【英文标题】:Function size vs execution speed 【发布时间】:2012-06-12 15:16:16 【问题描述】:

我记得在某处听说“大型函数可能具有更长的执行时间”,因为代码大小、CPU 缓存或类似的东西。

如何判断函数大小是否会影响我的应用程序的性能?我该如何优化呢?我有一个 CPU 密集型计算,我已经分成(与 CPU 内核一样多的线程)。主线程等待所有工作线程完成后再继续。

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

编辑:

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

我实际上正在寻找加快速度的方法。 我有可能通过重构来减小主跟踪函数的大小,我想知道我是否应该期望看到性能提升。

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

【问题讨论】:

重要的不是它有多大,而是你用它做什么。 :P @Oleksi 小功能的人都是这么说的。 您应该优化代码的清晰度和可读性。大型方法往往难以阅读,应尽可能避免使用。 是的,你们俩都提出了令人信服的论点:) 算法复杂度可能比大小更重要。 【参考方案1】:

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

因此,实际上无法说您当前的代码是否“对性能造成影响”。与您可以以不同方式构建代码的众多方式中的哪一种相比,这是一个成功吗?而且你不能合理地期望这种变化会对性能产生任何特别的影响。

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

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

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

不管怎样,你是从什么背景下听到的?我听到的最常见的一种说法是,函数内联有时会适得其反,因为有时代码膨胀的开销大于避免的函数调用开销。我不确定,但如果您的编译器支持,配置文件引导的优化可能会有所帮助。一个相当合理的配置文件引导优化是优先在执行次数较多的调用站点内联,使较冷的代码更小,首先加载和修复的开销更少,并且(希望)对指令的破坏性更小当它被拉入时缓存。比我更了解编译器的人会认真考虑这是否是一个好的配置文件引导的优化,因此决定是否实现它。

【讨论】:

【参考方案2】:

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

不过,将事物分解成多个较小的函数会更易于维护和阅读——尤其是在 6 个月后,当您忘记自己最初做了什么时。

【讨论】:

是的,同样,在构建项目时会删除空格。因此,使您的代码尽可能可读。这有助于以后维护它。【参考方案3】:

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

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

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

【讨论】:

好吧,我应该在我的问题中提供更多细节。我正在运行一个光线追踪器,它每个像素运行相同的功能 5,000 次左右 您可以分析代码以查看瓶颈在哪里,但与您在光线跟踪期间可能执行的计算相比,您多次调用它的事实可能仍然不是慢的部分 【参考方案4】:

这实际上与函数大小无关,而与您在其中所做的事情有关。根据您的工作,可能有一些方法可以对其进行优化。

【讨论】:

以上是关于函数大小与执行速度的主要内容,如果未能解决你的问题,请参考以下文章

技术浅谈Hadoop中mapreduce执行速度的问题

Postgresql 日期函数扫描每个分区中的每一行并且执行速度非常慢

动画 gif 与视频与画布 - 速度和文件大小

动态与静态内存在清洁度和速度方面的最佳实践

使用内在函数提高数组仿射变换的速度

Spark连接到MySQL并执行查询为啥速度会快