gpt4 book ai didi

GCC 编译器中的条件移动 (cmov)

转载 作者:行者123 更新时间:2023-12-05 00:57:30 28 4
gpt4 key购买 nike

我在某处看到 GCC 编译器在将我的代码转换为 ASM 时有时可能不喜欢使用条件 mov。

在哪些情况下它可能会选择执行条件 mov 以外的操作?

最佳答案

当分支的两边都很短时,编译器通常倾向于将 if-conversion 转换为 cmov,尤其是对于三元组,因此您总是分配一个 C 变量。例如if(x) y=bar; 有时不会优化到 CMOV 但 y = x ? bar : y; 确实更频繁地使用 CMOV。特别是当 y 是一个否则不会被触及的数组条目时:引入它的非原子 RMW 可能会创建源中不存在的数据竞争。 (编译器无法发明对可能共享对象的写入。)

if 转换合法但显然无利可图的一个明显例子是当 if/else 的两边都有大量工作时。例如一些乘法和除法,整个循环和/或表查找。即使 gcc 可以证明两边都运行并在最后选择一个结果是安全的,它也会看到做更多的工作不值得避免一个分支。

If 转换为数据依赖(无分支 cmov)甚至仅在有限的情况下才有可能。例如Why is gcc allowed to speculatively load from a struct?显示了可以/不能完成的情况。其他情况包括进行 C 抽象机没有的内存访问,编译器无法证明它不会出错。或者可能有副作用的非内联函数调用。

另请参阅这些关于 gcc 使用 CMOV 的问题。

另见 Disabling predication in gcc/g++ - 显然 gcc -fno-if-conversion -fno-if-conversion2 将禁用 cmov。

有关 cmov 损害性能的情况,请参阅 gcc optimization flag -O3 makes code slower than -O2 - GCC -O3 需要配置文件引导优化以使其正确并为 if 使用分支,结果证明是高度可预测的。 GCC -O2 一开始就没有进行 if 转换,即使没有 PGO 分析数据。

另一个例子:Is there a good reason why GCC would generate jump to jump just over one cheap instruction?

GCC seemingly misses simple optimization显示了三元在两半都有副作用的情况:三元不像 CMOV:甚至只有一侧被评估为副作用。

AVX-512 and Branching显示了一个 Fortran 示例,其中 GCC 需要源代码更改的帮助才能使用无分支 SIMD。 (相当于标量 CMOV)。这是不发明写入的情况:对于源不会写入的元素,它不能将读取/分支转换为读取/可能修改/写入。 自动矢量化通常需要If-conversion。

关于GCC 编译器中的条件移动 (cmov),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60019582/

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