使用 inline 关键字定义函数
#include <chrono>
#include <iostream>
using namespace std;
using namespace chrono;
inline int minus_ab(int a, int b) {
return a - b;
}
inline int add_ab(int a, int b) {
return a + b;
}
inline int multi_ab(int a, int b) {
return a * b;
}
int main(int argc, char** argv){
auto tick = high_resolution_clock::now();
int x;
int max_kRound = atoi(argv[1]);
int a=1, b=2;
for (int i=0; i<max_kRound*1000; i++) {
x = add_ab(a, b);
x = minus_ab(a, b);
x = multi_ab(a, b);
}
auto tock = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(tock - tick);
cout << "max round= " << max_kRound << "k" << endl;
cout << duration.count() / 1000 << " ms" << endl;
}
真正 inline 的写代码
...
for (int i=0; i<max_kRound*1000; i++) {
x = a+b;
x = a-b;
x = a*b;
}
...
上面两个程序我分别设置循环数为 1e9 ,结果第一个程序大概是第二个的三倍时间。我理解的 inline 是在编译阶段把函数中的代码拷贝到函数调用出,所以两个代码应该是等价的,为什么性能上有差别?
另外我还尝试去掉 inline
结果速度比用 inline
还快。是我对 inline
的理解不对吗?
1
yianing 2022-11-26 10:30:08 +08:00 via Android 1
inline 大多还是用作多次定义用的,但是有 static 一般也不用 inline ,内联这个语意要看编译器,https://en.cppreference.com/w/cpp/language/inline
|
2
wudicgi 2022-11-26 11:16:16 +08:00 1
先看看汇编,是否真的把代码内联进去了。或者是汇编代码有什么其他差异
inline 修饰符本身不是强制的, MSVC 有 __forceinline, gcc 有 __attribute__((always_inline)) 修饰符强制内联 |
3
AlohaV2 2022-11-26 11:23:32 +08:00
加-O3 再试试
|
4
ivan_wl 2022-11-26 11:26:49 +08:00
你这个代码里对 x 一番操作,最后又没有使用 x ,这个 x 可能会被优化掉的吧
|
5
disk 2022-11-26 11:52:01 +08:00
inline 只是建议,你这段代码不好,不开优化不会展开,开了整个循环直接被优化掉
|
6
codehz 2022-11-26 11:52:31 +08:00
inline 的语义早就改了,甚至和 inline 这个词本来的意思都不一样了,强制或者建议两个都不是,唯一的用途就是打破 ODR 可以多次定义,正因为如此,inline 也可以被用在变量上了
|
7
Opportunity 2022-11-26 11:53:08 +08:00
都是巧合,你这代码开 o2 就把循环体全优化掉了,实际就是给 atoi 计时
|
8
agagega 2022-11-26 12:01:15 +08:00 via iPhone
inline 更多的意义已经是改变编译器处理多个同名函数的方式了,具体有没有 inline ,效果变好没有,看汇编吧
|
9
xtreme1 2022-11-26 12:19:01 +08:00
当前的主流编译器都会忽略 inline 作为指令(建议)生成内联函数这个原始含义了.
真正的含义楼上都说完了 |
10
msg7086 2022-11-26 12:19:14 +08:00 via Android
1.你理解的当然不对。
2.纠结优化前的代码性能没有什么意义,谁发布软件会发非优化版的。优化后全变成常数根本测不出性能差距来。 你这些代码就算不会被优化掉,也会被优化成 simd 展开,到最后根本不会去执行加减乘除,都是跑 avx2 指令去了。 |
11
minami 2022-11-26 12:21:10 +08:00
inline 现在很大程度上取决于编译器怎么想,想要真正 inline ,还是用宏吧
|
12
icyalala 2022-11-26 12:27:45 +08:00
虽然但是。。
像上面说的,开了优化就没区别了。想要了解编译器怎么想的,去看看 https://godbolt.org/z/ee3ahjsx9 但你要想在没有优化时也 inline ,那就加个 __attribute__((always_inline)) |
13
Tanix2 2022-11-26 13:40:17 +08:00
第一个 diff 窗口是加 inline 和不加 inline 的汇编对比,第二个对比窗口是加 inline 和删掉函数手动 inline 的对比,优化等级都是-O1 ,main 函数是完全一样的: https://godbolt.org/z/xfxa8x14M
现代的编译器已经足够智能了,inline 的含义也发生了变化,一般的建议是只对可能出现在多个编译单元的函数用 inline ,比如定义在头文件中的函数。 |
14
dynos01 2022-11-26 18:40:35 +08:00
https://en.cppreference.com/w/cpp/language/inline
Since this meaning of the keyword inline is non-binding, compilers are free to use inline substitution for any function that's not marked inline, and are free to generate function calls to any function marked inline. Those optimization choices do not change the rules regarding multiple definitions and shared statics listed above. 编译器并不是见到 inline 就一定会内联一个函数。多数情况下,编译器比程序员更了解一个函数适合不适合 inline ,所以就不用操心这个问题了。 |
15
Jooooooooo 2022-11-26 21:45:41 +08:00
因为你测性能的代码完全是错的.
|
16
dazhangpan 2022-11-27 18:09:34 +08:00
现在还有对底层性能优化感兴趣的人啊 XD
|