gpt4 book ai didi

c - gcc 是否自动 "unroll"if 语句?

转载 作者:太空狗 更新时间:2023-10-29 17:01:39 27 4
gpt4 key购买 nike

假设我有一个看起来像这样的循环:

for(int i = 0; i < 10000; i++) {
/* Do something computationally expensive */
if (i < 200 && !(i%20)) {
/* Do something else */
}
}

其中一些琐碎的任务被困在只运行几次的 if 语句后面。我一直听说“循环中的 if 语句很慢!”因此,为了(略微)提高性能,我将循环分成:

for(int i = 0; i < 200; i++) {
/* Do something computationally expensive */
if (!(i%20)) {
/* Do something else */
}
}

for(int i = 200; i < 10000; i++) {
/* Do something computationally expensive */
}

gcc(带有适当的标志,如 -O3)会自动将一个循环分成两个,还是它只是展开以减少迭代次数?

最佳答案

为什么不直接反汇编程序自己看看呢?但我们开始吧。这是测试程序:

int main() {
int sum = 0;
int i;
for(i = 0; i < 10000; i++) {
if (i < 200 && !(i%20)) {
sum += 0xC0DE;
}
sum += 0xCAFE;
}
printf("%d\n", sum);
return 0;
}

这是用 gcc 4.3.3 和 -o3 编译的反汇编代码中有趣的部分:

0x08048404 <main+20>:   xor    ebx,ebx
0x08048406 <main+22>: push ecx
0x08048407 <main+23>: xor ecx,ecx
0x08048409 <main+25>: sub esp,0xc
0x0804840c <main+28>: lea esi,[esi+eiz*1+0x0]
0x08048410 <main+32>: cmp ecx,0xc7
0x08048416 <main+38>: jg 0x8048436 <main+70>
0x08048418 <main+40>: mov eax,ecx
0x0804841a <main+42>: imul esi
0x0804841c <main+44>: mov eax,ecx
0x0804841e <main+46>: sar eax,0x1f
0x08048421 <main+49>: sar edx,0x3
0x08048424 <main+52>: sub edx,eax
0x08048426 <main+54>: lea edx,[edx+edx*4]
0x08048429 <main+57>: shl edx,0x2
0x0804842c <main+60>: cmp ecx,edx
0x0804842e <main+62>: jne 0x8048436 <main+70>
0x08048430 <main+64>: add ebx,0xc0de
0x08048436 <main+70>: add ecx,0x1
0x08048439 <main+73>: add ebx,0xcafe
0x0804843f <main+79>: cmp ecx,0x2710
0x08048445 <main+85>: jne 0x8048410 <main+32>
0x08048447 <main+87>: mov DWORD PTR [esp+0x8],ebx
0x0804844b <main+91>: mov DWORD PTR [esp+0x4],0x8048530
0x08048453 <main+99>: mov DWORD PTR [esp],0x1
0x0804845a <main+106>: call 0x8048308 <__printf_chk@plt>

正如我们所见,对于这个特定的例子,不,它没有。我们只有一个从 main+32 开始到 main+85 结束的循环。如果您在阅读汇编代码时遇到问题 ecx = i; ebx = 总和。

但您的里程数仍然可能会有所不同 - 谁知道这种特定情况下使用了哪些启发式方法,因此您必须编译您想到的代码并查看更长/更复杂的计算对优化器有何影响。

尽管在任何现代 CPU 上,分支预测器都能在如此简单的代码上表现出色,因此在任何一种情况下您都不会看到太多性能损失。如果您的计算密集型代码需要数十亿个周期,那么少量错误预测的性能损失是多少?

关于c - gcc 是否自动 "unroll"if 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5017785/

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