缓存未命中不论出现在内部缓存中,还是出现在外部缓存中,都会降低程序的性能;而页错误由于会转到二级存储中获得程序指令和数据,也会降低程序的性能。
CPU 缓存命中可以花费程序 10–20 个时钟周期。外部缓存命中可以花费 20–40 个时钟周期。页错误可以花费 1,000,000 个时钟周期(假定处理器每秒处理 500,000,000 个指令并且一个页错误是 2 毫秒)。因此,编写减少缓存未命中和页错误数的代码对程序执行最重要。
程序慢的一个原因是它们接受的页错误比需要的多,或者未命中缓存的频率比需要的高。为避免此问题,使用具有良好引用地址的数据结构很重要,这意味着将相关的事物合在一起。有时看上去很棒的数据结构由于引用地址不好而变得很糟,有时正好相反。这里是两个示例:
动态分配的链接表可以降低程序性能,因为当搜索项或者在表中遍历到末尾时,每个跳过的链接都可能未命中缓存或导致页错误。基于简单数组的表实现由于较好的缓存和较少的页错误,实际上可能快得多,即使考虑到数组更难增长的事实,它仍然可能更快。
使用动态分配的链接表的哈希表可以降低性能。通过扩展,使用动态分配的链接表存储内容的哈希表的性能可能显著降低。事实上,在最后的分析中,通过数组的简单线性搜索实际上可能更快(取决于具体的情况)。基于数组的哈希表(所谓的“关闭散列”)是通常具有极佳的性能但却经常被忽略的实现。