简体   繁体   English

c 中全局变量的性能影响

[英]performance implications of global variables in c

I have 5 functions which gets called 10000+ times (on an average).我有 5 个函数,它们被调用了 10000 多次(平均)。 All of them modifies/uses certain variables.它们都修改/使用某些变量。

I know it is bad practice to have global variables.我知道拥有全局变量是不好的做法。 But for performance sake, does it make sense to keep them global and not pass them around - specially when I am making function call these many times?但是出于性能考虑,让它们保持全局而不是传递它们是否有意义 - 特别是当我多次调用 function 时?

OR I am not going to gain much in terms of performance?或者我不会在性能方面获得太多收益?

Do not introduce global variables/global state for performance purposes.不要出于性能目的引入全局变量/全局 state。 This is misguided, contrary to all good coding practices, and usually will not help performance (it might even hurt).这是被误导的,与所有良好的编码实践相反,并且通常不会提高性能(甚至可能会受到伤害)。

If you're finding it too costly to pass around lots of variables, you can put them all in a context struct and pass a single pointer to the struct .如果您发现传递大量变量的成本太高,您可以将它们全部放在上下文struct中,并将单个指针传递给struct This way you avoid creating global state (even static storage duration variables are global state) which prevents your code from being usable in multiple instances.这样可以避免创建全局 state(甚至static存储持续时间变量都是全局状态),这会阻止您的代码在多个实例中可用。 The cost is virtually zero, and in fact it will be less costly than global variables in position-independent code (shared libraries or position-independent executables).成本几乎为零,实际上它比位置无关代码(共享库或位置无关可执行文件)中的全局变量成本更低。

You may see a small performance improvement by reducing the number of parameters that are passed to your functions, by pre-allocating variables (eg. global or static variables)通过减少传递给函数的参数数量,通过预分配变量(例如,全局变量或 static 变量),您可能会看到性能的小幅提升

The change in performance is absolutely going to depend on a number of things, not the least of which is the platform that you're developing on.性能的变化绝对取决于许多因素,其中最重要的是您正在开发的平台。 If you're developing for a tiny microprocessor the time taken to copy parameters onto the stack (from the calling function) and the time taken to access the stack may be a significant enough proportion of the total execution time to warrant it.如果您正在为微型微处理器开发,则将参数复制到堆栈(从调用函数)所花费的时间以及访问堆栈所花费的时间可能占总执行时间的相当大的比例以保证它。

Note that in the situation where the time taken to pass parameters is significant you may find that some of the other suggestions (eg. passing pointers to structures, passing pointers to static variables) will not provide any benefit either.请注意,在传递参数所花费的时间很长的情况下,您可能会发现其他一些建议(例如,传递指向结构的指针、传递指向 static 变量的指针)也不会提供任何好处。 Using global variables does give the compiler/linker the opportunity to hard code access to those variables rather than having to access them indirectly from a pointer on the stack.使用全局变量确实使编译器/链接器有机会硬编码访问这些变量,而不必从堆栈上的指针间接访问它们。 This is particularly pertinent to processors that don't have any cache.这尤其适用于没有任何缓存的处理器。

Of course this is all very target dependent, and highly dependent on the instruction set of the processor that you're using.当然,这一切都非常依赖于目标,并且高度依赖于您正在使用的处理器的指令集。 On any platform with a reasonable instruction set you should see an improvement.在任何具有合理指令集的平台上,您都应该看到改进。

However, measures like this should only be taken after profiling this code.但是,只有在分析此代码后才应采取此类措施。 On most platforms, with any non-trivial function, the time taken to pass the parameters and access them is insignificant.在大多数平台上,对于任何重要的 function,传递参数和访问它们所花费的时间都是微不足道的。 Any potential performance gain would come at the cost of more difficult maintenance of the code.任何潜在的性能提升都将以代码维护更加困难为代价。

It is very likely that you would achieve greater performance gains by using other optimisation techniques.通过使用其他优化技术,您很可能会获得更大的性能提升。 Check this question for some methods to try.检查问题以尝试一些方法。


Edit: I see from one of your comments that you are still in the design phase of this project.编辑:我从您的一条评论中看到您仍处于该项目的设计阶段。

It is too early in the process to be making optimisations like this.现在进行这样的优化还为时过早。 At this stage you'll have a far greater impact on performance by optimising the algorithms you use than minimising at the instruction level like this.在这个阶段,通过优化您使用的算法,您将对性能产生更大的影响,而不是像这样在指令级别最小化。

static variables is C have file scope, and they might be sufficient in your case - provided you can group your functions into 1 file. static 变量是 C 有文件 scope,在您的情况下它们可能就足够了 - 只要您可以将函数分组到 1 个文件中。 And for me static variables are several orders of magnitude less problematic than globals.对我来说,static 变量的问题比全局变量小几个数量级。

One often overlooked issue is that variables declared inside a function body will be allocated on the stack, whereas static variables are typically allocated from a less confined memory pool called bss.一个经常被忽视的问题是,在 function 主体中声明的变量将在堆栈上分配,而 static 变量通常从称为 bs.bs. 的不太受限的 memory 池中分配So, having all variables neatly defined inside functions can lead to stack exhaustion problems, and that can be avoided in a quite clean way with statics.因此,在函数内部整齐地定义所有变量可能会导致堆栈耗尽问题,而这可以通过使用静态的非常干净的方式来避免。

I would go as far as saying that global variables will probably be slower than passing parameters.我会 go 说全局变量可能会比传递参数慢。 Parameters live on the stack which is heavily used and will therefore most likely be in cache.参数存在于堆栈中,该堆栈被大量使用,因此很可能在缓存中。 Global variables live in static space which is used a lot less and therefore less likely to be in cache making memory lookups a lot slower.全局变量存在于 static 空间中,该空间使用较少,因此不太可能在缓存中,这使得 memory 查找速度要慢得多。 Due to caching considerations, your jump (to the new function) may well be the slowest part of the whole function call operation.由于缓存的考虑,您的跳转(到新函数)很可能是整个 function 调用操作中最慢的部分。

If your functions are small,look at inlining them.如果您的功能很小,请查看内联它们。 If they are big, chances are that pushing one or two words on the stack will make minimal difference.如果它们很大,那么将一两个单词压入堆栈的可能性很小。

Also note that use of the stack for parameter passing is very much an x86 thing.另请注意,使用堆栈进行参数传递在很大程度上是 x86 的事情。 ARM and other architectures that have a large number of registers will normally used some registers for param passing that is extremely fast. ARM 和其他具有大量寄存器的架构通常会使用一些寄存器进行参数传递,速度非常快。

On some embedded microcontrollers , there may be performance advantages to using global variables instead of parameters, but this is highly machine-dependent .在某些嵌入式微控制器上,使用全局变量而不是参数可能会带来性能优势,但这与机器高度相关

When using a typical 8-bit microcontroller compiler (HT-PICC18), for example, the cost of setting a global variable is two instructions/two cycles per byte.例如,当使用典型的 8 位微控制器编译器 (HT-PICC18) 时,设置全局变量的成本是每字节两条指令/两个周期。 Passing one single-byte parameters costs instruction/one cycle.传递一个单字节参数需要花费指令/一个周期。 Passing two or more bytes of parameters cost two cycles per byte.传递两个或更多字节的参数每个字节花费两个周期。 Thus, the most efficient way to pass two single-byte parameters is to pass one as a parameter and one as a global.因此,传递两个单字节参数的最有效方法是将一个作为参数传递,一个作为全局参数传递。

On an Introl compiler for the 68HC11, routines which have any auto variables or parameters require a multi-instruction prologue and epilogue which can be omitted if all variables are static and parameters are passed as globals.在 68HC11 的 Introl 编译器上,具有任何自动变量或参数的例程需要多指令序言和结尾,如果所有变量都是 static 并且参数作为全局变量传递,则可以省略它们。 If a routine will use any locals or parameters, however, the marginal cost of using locals and parameters for everything else is negligible.但是,如果例程将使用任何局部变量或参数,则在其他所有事物中使用局部变量和参数的边际成本可以忽略不计。

On the ARM, even without a cache, the reverse situation often applies: accessing auto variables or parameters will often be faster than accessing global variables.在 ARM 上,即使没有缓存,也经常出现相反的情况:访问自动变量或参数通常比访问全局变量更快。 The auto variables and parameters will either be in a register, or else will be at a directly-accessible known offset from an address stored in a register.自动变量和参数要么在寄存器中,要么在寄存器中存储的地址的可直接访问的已知偏移量处。 Accessing global variables, by contrast, will often be a two-step process: first load the address of the global variable, and then access the variable itself.相比之下,访问全局变量通常需要两个步骤:首先加载全局变量的地址,然后访问变量本身。

People generally try to stay away from global parameters unless they really need them (ie unless something genuinely has global state).人们通常会尽量远离全局参数,除非他们真的需要它们(即,除非某些东西真正具有全局状态)。 Especially for multi-threaded applications the use of global parameters can make things more difficult than they need to be.特别是对于多线程应用程序,使用全局参数会使事情变得比实际需要的更加困难。

In terms of performance, I have heard a few people imply that access to global variables could be faster in some cases, although I find it hard to believe, but the only way to be sure is to actually do some benchmarking for you particular case.在性能方面,我听到一些人暗示在某些情况下访问全局变量可能会更快,尽管我觉得很难相信,但唯一可以确定的方法是为您的特定情况实际做一些基准测试。

Personally, I would never do this.就个人而言,我永远不会这样做。 I would think about the way that parameters were passed to the functions (make sure it's by pointer, rather than by copy, for instance, in the case of large data types) and ensure that the correct (best) optimisation settings were being passed to the compiler.我会考虑将参数传递给函数的方式(确保它是通过指针,而不是通过复制,例如,在大数据类型的情况下)并确保将正确的(最佳)优化设置传递给编译器。

Hope this helps.希望这可以帮助。

I think you're not going to improve performances by replacing parameters with global variables.我认为您不会通过用全局变量替换参数来提高性能。

Anyway if you wanna do this you can also consider to declare all functions and variables in the same file and declare variables as static.无论如何,如果你想这样做,你也可以考虑在同一个文件中声明所有函数和变量,并将变量声明为 static。 In that way only functions declared in the same file can access them.这样,只有在同一文件中声明的函数才能访问它们。

See here看这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM