C++ 代码膨胀何时开始对性能产生显著影响?

C++ 代码膨胀何时开始对性能产生显著影响?,c++,performance,C++,Performance,我希望在我的一个OpenGL项目中向模板做一个巨大的转变,主要是为了乐趣和学习体验。我计划在执行此操作时仔细观察可执行文件的大小,看看臭名昭著的膨胀发生了多少。目前,当我喜欢速度时,发布版本的大小大约为580KB,而当我喜欢大小时,发布版本的大小大约为440KB 是的,这是一个很小的项目,事实上,即使我的可执行文件的大小是它的10倍,它仍将是5MB左右,以今天的标准来看,这似乎不大。。。还是这样?这就引出了我的问题。速度是否与大小成正比,或者在某些临界点上是否存在跳跃和停滞,这些临界点我应该保持

我希望在我的一个OpenGL项目中向模板做一个巨大的转变,主要是为了乐趣和学习体验。我计划在执行此操作时仔细观察可执行文件的大小,看看臭名昭著的膨胀发生了多少。目前,当我喜欢速度时,发布版本的大小大约为580KB,而当我喜欢大小时,发布版本的大小大约为440KB


是的,这是一个很小的项目,事实上,即使我的可执行文件的大小是它的10倍,它仍将是5MB左右,以今天的标准来看,这似乎不大。。。还是这样?这就引出了我的问题。速度是否与大小成正比,或者在某些临界点上是否存在跳跃和停滞,这些临界点我应该保持在以下?(如果是,具体的阈值是什么?

速度取决于许多因素。这就是为什么明智的程序设计遵循良好的架构原则是好的

但是,如果应用程序设计正确,可执行文件的实际大小与其性能几乎没有关系。通过分析应用程序和修复缓慢部分而获得的性能改进只会影响代码的一小部分(10%或更少)

在任何给定时刻(除非程序是令人尴尬的并行程序,或者代码中的性能关键部分恰好相当大),处理器中只执行了一小段代码

一级缓存尤其如此。原则上,大型程序的执行速度要比小型程序慢,但实际上,如果性能关键部分足够小,那么性能关键代码应该留在一级缓存中


请记住,一个紧凑、高性能的循环只需将自身加载到一级缓存中一次,第一次是通过循环加载的。

我没有注意到OpenGL项目的大小与性能之间存在很大的相关性,但是我也从未真正承担过一个大型项目。编写高效的代码是更重要的。你想干什么?性能上的额外提高对您的应用程序有多重要?专注于编写好的代码,你应该会很好。作为一种学习经验,请尝试使用这些模板。当然,要定期提交,以便您可以随时返回。

在实践中,总体执行通常取决于您使用的算法

在可执行文件大小的情况下,您会发现速度与CPU指令缓存大小和给定缓存线的长度有关。当您从一个缓存级别跳转到下一个较低的缓存时,您会注意到一个较大的延迟。但是,编译器的工作是优化和排列代码,以便通常线性执行(如果可能的话)


除非您希望您的软件只在一台机器上运行,否则不应调整到特定的CPU。在一般情况下,为了获得最大的速度,良好的设计、良好的算法选择和良好的编译器调优将比可执行文件的大小更重要。

膨胀更多地与程序在同一时间的执行量有关,而不是与可执行文件的大小有关

一个简单而直接的例子是:假设我有一个程序,返回前100万个素数。我可以用一个函数来计算,或者我可以把这个列表硬编码为一个字符串,然后打印这个字符串。后一个程序要大得多,但生成该列表所占用的资源要少得多


“臃肿”只是意味着它会从其他程序中占用大量资源,因为它会将太多的进程和线程强制放到内存中。通常,你的操作系统只是分配这些进程,这也可能意味着它“一直在计算”,因此,一个需要几天时间来计算一个非常大的素数列表的非常小的程序实际上是一个“膨胀”,因为它一直在计算。

在大多数现代处理器上,位置将比大小更重要。如果您可以将当前执行的所有代码和大部分数据保留在一级缓存中,您将看到巨大的成功。如果您到处乱跳,您可能会强制代码或数据从缓存中出来,然后不久又需要它

根据我的经验,“面向数据的设计”对代码和数据局部性都有帮助。您可能会对()感兴趣,它很好地展示了如何以这样一种方式处理问题,从而获得良好的数据和代码局部性


(顺便说一句,整个缓存大小和局部性是“针对大小优化”在某些情况下优于“针对速度优化”的原因之一。)

可执行文件的大小其实并不重要。重要的是“活动”代码的大小,即应用程序实际频繁执行的代码。不幸的是,这很难量化。对于一个简单的近似值,您可以分析您的应用程序,采用占执行时间90%的过程,并将它们的代码大小相加

大多数现代处理器都有64KB或128KB指令缓存,因此它有助于将活动代码保持在此大小以下。下一个阈值是L2大小,可以是几兆字节。

可执行文件“膨胀”对性能的影响小于以下两个因素(它们是相关的,但不相同)

  • 代码工作集大小
  • 数据工作集大小
  • 程序执行一个工作单元(如渲染帧)所需运行的代码量将影响指令缓存命中率和页表命中率。然而,如果90%的工作是在一个完全适合i-cache的小函数中完成的,那么整个程序的代码大小将只占其他10%

    同样地,对于数据,如果您的程序每帧必须接触100MB的数据,那么这将比一级、二级或三级缓存中具有工作集的程序的性能差得多


    因此,其实不是可执行文件有多大,而是一次使用了多少“东西”