【发布时间】:2019-02-03 22:17:30
【问题描述】:
您好,我正在阅读一本比较条件数据传输的教科书 和装配中的条件控制转移:
上面是gotodiff(条件跳转)
不知道为什么
v = test-expr ? then-expr : else-expr;
比以下更有效:
if (!test-expr)
goto false;
v = true-expr;
goto done;
false:
v = else-expr;
done:
假设分支预测硬件会正确猜测 大约 50% 的时间,所以如果我们每次运行两次(第一次预测成功,第二次预测不成功,gotodiff 总共有 6+8 = 14 条指令要执行,而 cmovdiff 将有 8+8 = 16条指令,为什么cmovdiff比gotodiff效率更高?
【问题讨论】:
-
您在 C 级别上的问题没有多大意义,因为任何打开优化的体面 C 编译器都将以相同的方式进行翻译(条件 mov 或分支,取决于编译目标) .在汇编级别的问题是,指令数在现代 CPU 上并不那么重要,它们通常可以在“单个”时钟中执行多达 2 条以上的指令,但这需要在前面的步骤中完成大量工作作为准备。分支是非常昂贵的操作,因为准备工作要么缺少一个选项,要么必须推测两个分支。
-
虽然条件
mov仅使结果难以预测,因此任何依赖于eax的进一步指令都必须等到条件最终确定并且结果已知,但即使是那些也可能已经 fetch+decoded+prepared,并且其他不依赖于这些指令的指令甚至可以完全执行(乱序),因此条件 mov 对并行乱序复杂事物的压力较小,即现代 x86 CPU。 (推测整个分支比在单个队列中停止依赖指令要困难得多)。
标签: assembly cpu instruction-set