Ida*_* C. 2 c assembly gcc compiler-optimization
我在某处看到 GCC 编译器有时更喜欢在将我的代码转换为 ASM 时不使用条件 mov。
在什么情况下它可能会选择做条件 mov 以外的事情?
当分支的两边都很短时,编译器通常倾向于将 if 转换为 cmov,特别是对于三元,因此您总是分配一个 C 变量。例如,if(x) y=bar;
有时不会针对 CMOV 进行优化,但y = x ? bar : y;
会更频繁地使用 CMOV。特别是当y
一个数组条目不会被触及时:引入它的非原子 RMW 可能会创建源中不存在的数据竞争。(编译器不能发明对可能共享对象的写入。)
if-conversion 合法但显然无利可图的一个明显例子是 if/else 双方都有很多工作。例如一些乘法和除法、整个循环和/或表查找。即使 gcc 可以证明两边运行并在最后选择一个结果是安全的,它也会看到做更多的工作不值得避免分支。
If-conversion to a data-dependency (branchless cmov) 仅在有限的情况下才有可能。例如,为什么允许 gcc 从结构中推测加载?显示了可以/不能完成的情况。其他情况包括进行 C 抽象机没有的内存访问,编译器无法证明不会出错。或者可能有副作用的非内联函数调用。
另请参阅有关让gcc 使用 CMOV 的这些问题。
另请参阅禁用 gcc/g++ 中的预测- 显然gcc -fno-if-conversion -fno-if-conversion2
将禁用 cmov 的使用。
对于 cmov 损害性能的情况,请参阅gcc 优化标志 -O3 使代码比 -O2 慢- GCC-O3
需要配置文件引导的优化以使其正确并使用分支来if
证明是高度可预测的。-O2
即使没有 PGO 分析数据, GCC也没有首先进行 if 转换。
另一个例子:GCC 会生成跳转以跳过一个便宜的指令是否有充分的理由?
GCC 似乎错过了简单的优化显示了一个三元在两半都有副作用的情况:三元不像 CMOV:只有一侧甚至评估了副作用。
AVX-512 和分支显示了一个 Fortran 示例,其中 GCC 需要源更改的帮助才能使用无分支SIMD。(相当于标量 CMOV)。这是不发明写入的情况:对于源不会写入的元素,它无法将读取/分支转换为读取/可能修改/写入。 自动矢量化通常需要 if 转换。
归档时间: |
|
查看次数: |
748 次 |
最近记录: |