8. 第一次 vs 重复运行

优质
小牛编辑
127浏览
2023-12-01

一片代码往往在第一次运行时比重复运行消耗更多的时间。 原因见下:

1. 从 RAM 读入代码到cache花去了比运行它更多的时间。
2. 代码操作的所有数据都必须加载到cache, 这比执行那些操作更花时间。 当代码重复运行的时候, 数据几乎都在 cache 里。
3. 跳转指令在第一次运行的时候并不在分支目的缓存(branch target buffer,简称BTB)里, 因此一般都不能正确的预测。 见第22章。
4. PPlain 上, 代码的解码是个瓶颈。 如果花掉一个时钟周期去检测指令长度, 那么就不可能在一个时钟周期解码两条指令, 因为处理器不知道第二条指令从那里开 始的。 PPlain 通过记住上次运行后保存在cache里的每条指令的长度来解决这个问题。 这样做的结果是, PPlain上第一次执行时,指令如果不是只有1个字节长的话就不会配对执行。 PMMX, PPro, PII 和 PIII 在第一次解码却没有这个问题。

因为这四个原因,在循环内部的一段代码第一次运行通常比随后的运行花去更多的时间。

如果你使用了一个很大的循环而不能放入代码cache,将导致效率下降,因为它们不能在 cache 运行。 因此你应该重新组织一下循环使cache能放下它们。

如果你有非常多的跳转,调用,分支在循环里,就会反复的产生分支目的缓存失败。

同样的,如果循环反复操作一个对数据cache而言太大的数据结构,也会一直得到数据cache不命中的惩罚。