gpt4 book ai didi

gcc - gcc 中 __always_inline 和 __never_inline 的异常(exception)情况是什么?

转载 作者:行者123 更新时间:2023-12-04 01:30:40 25 4
gpt4 key购买 nike

Andrei Alexandrescu 在 talk that he presented at cppcon 中提到当定义和使用 __always 内联宏时,gcc 并不总是内联,对于 __never_inline 则反之亦然。我找不到很多关于发生在哪些场景中的文档,所以有人告诉我吗?

最佳答案

I couldn't find much documentation about which scenarios that occurs in, so someone tell me?

Could you give a code example?

将函数作为函数指针传递并从不同的翻译单元调用它(即使是从相同的翻译单元假设优化是 -O0 或 -Os 并且它的大小更好或者真的只是...“幸运”)将有效地禁止内联函数的可能性:

cat << EOF > main.c
__attribute__((__always_inline__))
static inline
void f(void) {
printf("Hey buddy!\n");
}

extern void call_fp(void (*fp)(void));

int main() {
call_fp(f);
}
EOF

cat << EOF > g.c
void call_fp(void (*fp)(void)) {
printf("Hey pal!");
fp();
}
EOF

编译和检查:

$ gcc -g -Ofast main.c g.c && objdump -S ./a.out | grep '<main>:\|<call_fp>:'
0000000000001050 <main>:
int main() {
1050: 48 83 ec 08 sub $0x8,%rsp
call_fp(f);
1054: 48 8d 3d 35 01 00 00 lea 0x135(%rip),%rdi # 1190 <f>
################################### vvvvv NOT INLINED ###############
105b: e8 40 01 00 00 callq 11a0 <call_fp>
}
1060: 31 c0 xor %eax,%eax
1062: 48 83 c4 08 add $0x8,%rsp
1066: c3 retq
1067: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
106e: 00 00
--
00000000000011a0 <call_fp>:
void call_fp(void (*fp)(void)) {
11a0: 53 push %rbx
printf("Hey pal!");
11a1: 31 c0 xor %eax,%eax
void call_fp(void (*fp)(void)) {
11a3: 48 89 fb mov %rdi,%rbx
printf("Hey pal!");
11a6: 48 8d 3d 62 0e 00 00 lea 0xe62(%rip),%rdi # 200f <_IO_stdin_used+0xf>
11ad: e8 8e fe ff ff callq 1040 <printf@plt>
fp();
11b2: 48 89 d8 mov %rbx,%rax
}
11b5: 5b pop %rbx
fp();
################################### vvvv NOT INLINED ####################
11b6: ff e0 jmpq *%rax
11b8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
11bf: 00

您仍然可以使用 LTO 跨翻译单元进行优化:

$ gcc -g -flto -Ofast main.c g.c && objdump -S ./a.out | grep '<main>:' -A30
int main() {
1050: 48 83 ec 08 sub $0x8,%rsp
void call_fp(void (*fp)(void)) {
printf("Hey pal!");
1054: 48 8d 3d a9 0f 00 00 lea 0xfa9(%rip),%rdi # 2004 <_IO_stdin_used+0x4>
105b: 31 c0 xor %eax,%eax
105d: e8 de ff ff ff callq 1040 <printf@plt>
printf("Hey buddy!\n");
1062: 48 8d 3d a4 0f 00 00 lea 0xfa4(%rip),%rdi # 200d <_IO_stdin_used+0xd>
####################### Both call_fp() and f() were inlined!!!!!!!!!!!!!
1069: e8 c2 ff ff ff callq 1030 <puts@plt>
call_fp(f);
}
106e: 31 c0 xor %eax,%eax
1070: 48 83 c4 08 add $0x8,%rsp
1074: c3 retq
1075: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
107c: 00 00 00
107f: 90 nop

至于 __attribute__((__noinline__)) 我没有遇到 gcc 宁愿选择内联一个 __noinline__ 函数的可能情况。

关于gcc - gcc 中 __always_inline 和 __never_inline 的异常(exception)情况是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61091737/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com