设置条件语句以利用指令预取(现代x86)

时间:2012-10-30 20:57:50

标签: optimization assembly x86

我最近选择了Michael Abrash的汇编语言之禅(从1990年开始),并且正在阅读有关指令预取如何并不总是有利的部分,例如分支发生的情况(跳转) )。这是因为预取的所有指令不再是要执行的指令,因此必须提取更多指令。

这让我想起了Andre LaMothe的另一本旧书,游戏编程大师的诀窍中的优化,他建议在设置条件语句时,你最频繁(或预期) )路径第一。

例如:

if (booleanThatIsMostLikelyToBeTrue)
{
   // ...expected code
   // also the code that would've been prefetched
}
else
{
   // ...exceptional or less likely code
}

我的问题是:

1)LaMothe的优化建议考虑到这一点吗? (我不再有这本书)

2)这种优化在现代机器上仍然是一种有价值的编程习惯吗? (也许预取的处理方式与以前不同?)

2 个答案:

答案 0 :(得分:1)

这些优化通常很有用。但是,它通常是在您编写程序,对其进行分析并确定程序将从这些微优化中受益后执行的操作。

此外,许多现代编译器都有profile-guided optimization,这可以减轻您为了性能目的而扭曲代码的麻烦。

答案 1 :(得分:1)

您希望将代码设置为尽可能少地分支,然后在分支时向后分支。一个更可靠的方法来做到这一点就是总是做常见的事情然后测试异常:

做A; if(test)做B;

当然,必须安排这样做,以便如果B出现,A所做的任何事情都会被B反转。

Zen编程的目的是尝试完全消除If语句。因此,例如,不是循环10次(这需要退出条件测试),而是只写10次相同的语句,瞧!,no if语句。另一个例子是如果你循环一个列表,你使用一个sentinel退出循环,而不是测试一个索引值。

如果您在C中工作,可能很难模仿编译器执行您想要的操作。在IF语句中放置第一个或第二个内容对编译结果没有影响。请注意,使用正确的编译器选项至关重要。例如,在Visual C ++中使用/ O2(优化速度)会使编译效率产生巨大差异。