- 主题:函数嵌套调用很多层的话,会不会导致程序运行慢?
一个编译器程序有很多component, 每个component都通过统一的接口去调用别的component的对应函数,导致函数嵌套很深(稍微复杂点的目标文件一般都能到超过70层),这样会不会导致程序由于经常分配和释放堆栈而速度慢(我不清楚这里面的机制)?
如果是的话,gcc有什么编译选项能够优化这种情况吗?
--
FROM 116.4.9.*
分配/释放栈,主要是编译期间由编译器来计算,在运行时的开销是比较小的。
运行时分配、释放栈,只是一个栈帧寄存器的加减操作,
主要开销在函数参数的压栈上,出栈也基本就一条指令。
得先用性能工具证明瓶颈在这里,再做优化。
简单的优化一般是用inline,一般不是强制的。
--
FROM 123.118.187.*
调用层数深并不会显著地慢。
-O2 选项能够恰当地优化调用层数(在可能且合适的情况下)。
你得区分堆和栈。其机制可以通过简单学习汇编语言来了解。
再有就是2楼说的,先通过profiling来找到性能瓶颈。
【 在 il15 () 的大作中提到: 】
: 一个编译器程序有很多component, 每个component都通过统一的接口去调用别的component的对应函数,导致函数嵌套很深(稍微复杂点的目标文件一般都能到超过70层),这样会不会导致程序由于经常分配和释放堆栈而速度慢(我不清楚这里面的机制)?
: 如果是的话,gcc有什么编译选项能够优化这种情况吗?
--
FROM 220.248.9.*
多谢楼上的两位!
我跑了callgrind,用callgrind_annotate看了下输出,比较难看(如前面所说的,由于用了统一的入口,所以这入口不停的被调用)。
我稍候装个KCachegrind试试,不行的话就在里面统计时间,看看哪个子component所花的时间比较多
【 在 fanci 的大作中提到: 】
: 调用层数深并不会显著地慢。
: -O2 选项能够恰当地优化调用层数(在可能且合适的情况下)。
: 你得区分堆和栈。其机制可以通过简单学习汇编语言来了解。
: ...................
--
FROM 116.4.8.*
【 在 il15 的大作中提到: 】
: 一个编译器程序有很多component, 每个component都通过统一的接口去调用别的component的对应函数,导致函数嵌套很深(稍微复杂点的目标文件一般都能到超过70层),这样会不会导致程序由于经常分配和释放堆栈而速度慢(我不清楚这里面的机制)?
: 如果是的话,gcc有什么编译选项能够优化这种情况吗?
有影响。
某些情况用inline函数会好些。
--
FROM 221.221.51.*
原来我也认为调用开销无所谓。
直到一次测试STL的map。把一个调用优化成直接代码展开(inline)。结果性能差异巨大。
【 在 z16166 的大作中提到: 】
: 分配/释放栈,主要是编译期间由编译器来计算,在运行时的开销是比较小的。
: 运行时分配、释放栈,只是一个栈帧寄存器的加减操作,
: 主要开销在函数参数的压栈上,出栈也基本就一条指令。
: ...................
--
FROM 221.221.51.*