带和不带参数 C/C++ 的函数之间的执行时间
Execution time between functions with & without arguments C/C++
我只是想问一下执行时间有什么不同:
a)我们在main()
中声明了变量,并通过参数
b)我们有全局变量,可以不带参数直接从函数中访问
问题是我开始写一些应用程序,只是看到了一些关于这个的讨论,但我还没有写任何应用程序,使差异比ms更大
向函数传递参数涉及通常两个汇编指令之一:push param
(后来是pop param
)或mov ax, param
。由于处理器能够在一秒钟内做(很多)更多的事情,因此这种"优化"很可能不会被注意到(整个程序的几毫秒低于误差范围)
在函数参数的位置使用全局变量将导致代码中的巨大混乱,几乎不明显或可能没有性能增益。
所有这些都取决于所使用的CPU和编译器。
向函数传递参数时,可能会发生以下情况之一:
- 该参数存储在CPU寄存器中。这非常有效。
- 该参数存储在堆栈中。这是最常见的。它涉及到在函数启动/结束时将参数推入/从堆栈中取出的一些小开销。
- 参数根本不是一个新变量。相反,编译器内联函数并使用原始变量进行修改。这是你能得到的最高效率了。
使用全局变量会比使用堆栈稍微快一点。它不可能比使用CPU寄存器快:在函数内部,无论如何,在计算之前可能需要将值加载到这样的寄存器中。
应该注意的是,我们在这里和那里谈论一些CPU节拍。
我的建议:
- 除非您对所使用的特定CPU有深入的硬件知识,否则您不应该尝试任何类型的手动优化。如果您不了解这些知识,编译器将在99%的情况下比您更好地优化代码。因为编译器端口很可能是由给定系统的专家编写的。编译器也知道整体性能图,而程序员不知道,所以编译器更适合做优化。你不应该尝试任何形式的手动优化,除非你已经实际执行了正式的基准测试,并在程序中发现了瓶颈。全局变量的使用是非常糟糕和危险的。它们会导致面条式代码,而且它们不是线程安全的。
- 如果你正在编写一些高端桌面应用程序,如PC程序或手机应用程序,那么使用全局变量来提高性能是完全没有意义的。你所处的系统一开始就没有实时性能!在任何给定的时间,您的操作系统可能会决定在给您的程序手指时咀嚼数十亿个CPU节拍。所以不要追逐1或2个CPU节拍。
- 只有当您开发的嵌入式系统应用程序与硬件非常接近,并且同时具有硬实时性要求时,这些类型的手动优化才有意义。
堆栈操作非常高效,而且由于堆栈很可能位于缓存内存中,因此它们变得更加高效。这可以使使用堆栈比不使用它更快。
期望参数传递变量比全局变量快得多。在现代abi中,函数参数大多是通过CPU寄存器传递的,这些寄存器对CPU来说是立即可用的。
全局变量必须从(静态)内存中读取。更糟糕的是,静态内存是在它自己的内存页上分配的,这通常远离堆栈(或堆)内存。这意味着缓存丢失的可能性更大,这反过来又意味着访问会消耗大量的CPU周期。
显然这在很大程度上取决于你的使用模式
相关文章:
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 填充上编译器生成的复制构造函数之间的不一致
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 如何在"push_*()"和"emplace_*()"函数之间进行选择?
- 仅具有运算符()的结构和普通函数之间的实际区别
- 当两者都调用时,删除和析构函数之间的区别?
- Release() 和析构函数之间的区别?
- 调用 "project" 函数和调用 DLL 函数之间的区别
- C++模板和非模板函数之间的重载解析
- std::shared_ptr 和 std::unique_ptr 构造函数之间的不对称
- C++ 和 Lua 函数之间的交互与 3D 矢量参数
- 在结构函数之间传递文件路径 C++ 编辑:修复LNK2019错误
- 在C++同名的顶级函数之间进行选择
- 在成员函数之间传递const变量为数组的索引
- Helgrind 报告了使用 Singleton 及其构造函数之间可能存在的竞争
- 函数模板和函数之间奇怪的不一致"normal"
- 在c#和c函数之间传递值和指针
- 在C++中调用 malloc() 与"operator new"函数之间的实现差异
- 在函数之间传递相同的数组
- C++编译错误是由于使用 std::move 时运动构造函数与其他非运动构造函数之间的冲突