当我所做的只是将循环代码移动到函数中时,代码运行速度会慢10倍
Code runs ten times slower when all I did was move the loop code into a function
我正在运行下面的代码,它基本上做的很少。它只是将2和4相加1亿次,然后输出运行时间。
#include "time.h"
#include <iostream>
using namespace std;
void add (){
int tot = 2+4;
}
void main(){
int t = clock();
int count = 0;
while(count<100000000){
int tot = 2+4;
count++;
}
cout <<endl<< "runtime = " << fixed <<(double) (clock() - t) / CLOCKS_PER_SEC <<"s" << endl;
}
但我很感兴趣的是,当做完全相同的事情,但调用一个函数时,看到的时间差异。因此,我将"int tot = 2+4"一行替换为"add()"。
我原以为第二次运行时间会稍微长一点,但实际上长得多。第一次实现= .3s
,第二次实现= 3s
。
我理解调用函数需要使用堆栈来存储返回地址和存储本地数据。但是它一定做了很多更多的然后呢?
如果有人能向我解释到底是什么导致了运行时的巨大差异,或者也许我在做一些愚蠢的事情,那就太好了。正如Seth已经提到的,内联函数可能会得到优化。
在第一种情况下(在基本优化的情况下),很可能不是不断地将这两个数字相加,而是将2 + 4解析为6,只需简单地执行一个简单的
mov eax, 6 ;eax is just an example here or
mov tot_addr, 6 ; mem->mem mov
在第二种情况下,由于它是一个函数调用,系统必须
push 4 ;assuming 4 byte ints
push 4 ;wrote 2 to be clear that you have to push both variables
call add
之类的。因为需要为该函数创建调用堆栈(为了简单起见,请提交返回值push等)。一旦这个函数返回,堆栈指针需要被移回第一次push之前,然后RET会将指令指针设置回去。可以看到,这比执行简单的
要昂贵得多mov eax, 4
add eax, 2
如果你只是在做一个简单的(非优化的)添加,很可能是这样的
编辑:这里有一些关于内联函数的更多信息。当你内联函数时,它只是简单地取函数本身要做的任何功能,并将指令直接放在它引用的地方,而不是执行CALL指令并直接设置函数调用。例如,不用mov eax, 4
mov ecx, 2
push 4 ; size for return value
push eax
push ecx
call add
你会得到
mov eax, 4
mov exc, 2
add eax, ecx
代码:
int a = 4;
int b = 2;
int res = add(a, b);
将成为
int a = 4;
int b = 2;
int res = a + b;
假设您内联了add函数
相对于做其他事情,函数调用是非常昂贵的(比您想象的要昂贵),原因正是您提到的。尝试声明您的函数inline
和/或启用优化以恢复性能。
函数调用确实会给CPU带来比简单地推送返回地址和参数更多的工作。
在某些cpu上,您将获得管道停滞。甚至可能在读取下一条指令时i-cache丢失。这些很容易导致比你注意到的10倍更大的减速。
这就是为什么编译器会不遗余力地优化函数调用
相关文章:
- 我的代码运行良好,但在游戏循环中中断
- 通过窗口从C++代码运行 WSL 命令
- 如何使用 lldb 查找我的代码运行的位置
- 无法在 VS Code 上使用代码运行程序运行C++文件
- 我的代码运行良好,但现在当尝试将其制作成模板时,我遇到了许多看似无关的错误。这是怎么回事?
- Visual Studio代码运行环境
- 如何从C++代码运行自定义 GPU tensorflow::op?
- 在 ZeroMQ 中绑定订阅者套接字并连接发布者套接字会在代码运行时给出错误.为什么
- 代码运行缓慢
- .NET CORE 2 DLL引用带有C 代码运行时错误
- C++ 中控制台代码运行时的分段错误
- C++ 菜单代码 - 运行另一个类
- 以下代码运行后,如何在程序再次运行之前清除用户声明的变量 empName
- 当我使用此合并排序代码运行时,输出错误
- 有哪些优化技巧可以使我的代码运行得更快
- 使 C 代码能够作为C++代码运行
- 错误代码LNK1561阻止我的代码运行
- 如果我用代码块编译代码,为什么我的代码运行速度更快
- 更改Linux用户从C/C 代码运行时间
- 为什么这段代码运行这么慢