Bee*_*and 42 c c++ optimization
我最近在一篇关于 1996年编写的游戏编程的文章中读到,使用全局变量比传递参数更快.
这是真的,如果是这样,今天仍然如此吗?
Ste*_*end 43
简短的回答 - 不,优秀的程序员通过了解和使用适当的工具来使代码更快,然后以有条不紊的方式优化他们的代码不符合他们的要求.
更长的答案 - 这篇文章,在我看来并不是特别精心编写的,在任何情况下都不是关于程序加速的一般建议,而是'15种做更快的blits的方法'.无论你如何看待文章的优点,将其推断为一般情况都是缺少作者的观点.
如果我正在寻找性能建议,我会在一篇没有识别或显示单个具体代码更改的文章中放置零信任以支持示例代码中的断言,并且不建议测量代码可能是个好主意.如果您不打算如何更好地编写代码,为什么要包含它?
一些建议已经过时 - 很久以前,FAR指针在PC上停止了问题.
一个认真的游戏开发者(或任何其他专业程序员,就此而言)会对这样的建议大笑:
您可以完全取出断言,也可以
#define NDEBUG在编译最终版本时添加 .
我的建议,如果你真的希望评估这15个技巧中的任何一个的优点,并且因为这篇文章已经14年了,那就是用现代编译器编译代码(Visual C++ 10说)并尝试识别任何使用全局变量(或任何其他提示)的区域会使其更快.
[只是在开玩笑 - 我真正的建议是完全忽略这篇文章,并在你无法解决的工作中遇到问题时询问Stack Overflow的具体性能问题.这样,您获得的答案将经过同行评审,并得到示例代码或良好的外部证据以及当前的支持.
Pet*_* G. 27
当您从参数切换到全局变量时,可能会发生以下三种情况之一:
您将不得不测量性能,以便在非平凡的具体情况下看到更快的速度.这在1996年是真的,今天是真的,明天也是如此.
暂时搁置性能,大型项目中的全局变量引入了依赖关系,这几乎总是使维护和测试变得更加困难.
出于性能原因试图找到全局变量的合法用法时,我非常同意Preet的答案中的例子:微控制器程序或设备驱动程序中经常需要的变量.极端情况是处理器寄存器,专门用于全局变量.
在推理全局变量与参数传递的性能时,编译器实现它们的方式是相关的.全局变量通常存储在固定位置.有时,编译器会生成直接寻址以访问全局变量.但有时,编译器会再使用一个间接,并为globals使用一种符号表.IIRC gcc for AIX在15年前做到了这一点.在这种环境中,小类型的全局变量总是慢于本地和参数传递.
另一方面,编译器可以通过将参数传递到堆栈中来传递参数,方法是将它们传递给寄存器或两者的混合.
Cra*_*rks 22
每个人都已经给出了适当的警告答案,关于这是平台和程序特定的,需要实际测量时间等等.所以,所有已经说过,让我直接回答你的问题,针对x86和PowerPC上的游戏编程的具体情况.
在1996年,在某些情况下,将参数推送到堆栈上需要额外的指令,并且可能导致Intel CPU管道内的短暂停顿.在这些情况下,完全避免参数传递和从文字地址读取数据可能会有非常小的加速.
在大多数游戏机上使用的x86或PowerPC上都不再如此.使用全局变量通常比传递参数慢,原因有两个:
pmg*_*pmg 12
你是什么意思,"更快"?
我知道一个事实,用全局变量理解一个程序比没有一个程序花费了我更多的时间.
如果程序员花费的额外时间少于用户在使用全局变量运行程序时获得的时间,那么我会说使用global更快.
但考虑到该计划将由10人每天一次运行2年.而且没有全局变量需要2.84632秒而全局变量需要2.84217秒(增加0.00415秒).这比TOTAL运行时少727秒.在程序员时间方面,获得10分钟的运行时间并不值得引入全局.
Pre*_*gha 11
在某种程度上,任何避免处理器指令(即更短的代码)的代码都会更快.但是要快多少?不是特别的!另请注意,编译器优化策略可能会导致代码更小.
如今,这只是对非常特定的应用程序的优化,通常在超时间关键驱动程序或微控制代码中.
撇开可维护性和正确性的问题,基本上有两个因素可以控制全局数据与参数的性能.
当你创建全局时,你会避免复制.那稍快一些.当您按值传递参数时,必须将其复制,以便函数可以在其本地副本上工作,而不会损坏调用者的数据副本.至少在理论上.如果一些现代优化器确定您的代码表现良好,那么它们会做很棘手的事情.函数可能会自动内联,编译器可能会注意到函数对参数没有任何作用,只是优化掉任何复制.
当你创建一个全局时,你就是在缓存中.如果您的所有变量都包含在您的函数和一些参数中,那么数据将集中在一个地方.一些变量将在寄存器中,一些变量可能会立即存在于缓存中,因为它们彼此正确"相邻".使用大量全局变量基本上是缓存的病态行为.无法保证相同功能将使用各种全局变量.位置与使用没有明显的相关性.也许你有一个足够小的工作集,它在任何地方都没有任何区别,而且它们都会在缓存中结束.
所有这些只是加上我上面的海报所提出的观点:
当您从参数切换到全局变量时,可能会发生以下三种情况之一:
Run Code Online (Sandbox Code Playgroud)* it runs faster * it runs the same * it runs slower您将不得不测量性能,以便在非平凡的具体情况下看到更快的速度.这在1996年是真的,今天是真的,明天也是如此.
根据您的确切编译器的具体行为以及用于运行代码的硬件的精确详细信息,在某些情况下,全局变量可能会获得非常轻微的性能提升.这种可能性值得在一些运行速度太慢的代码上尝试.可能不值得投入,因为明天你的实验答案可能会改变.因此,正确的答案几乎总是采用"正确"的设计模式,避免更丑陋的设计.在故意尝试破坏您的项目之前,寻找更好的算法,更高效的数据结构等.从长远来看,收益会好得多.
而且,除了开发时间与用户时间参数之外,我将添加开发时间与摩尔时间参数.如果你认为摩尔定律每年会使计算机的速度再次降低一半,那么为了简单的整数,我们可以假设每周进展稳定1%.如果你正在寻找可以改善1%这样的事情的微优化,并且它会使项目因复杂化而增加一周,那么只需休息一周就会对用户的平均运行时间产生同样的影响.