从前,有个放羊娃,每天都沿着I/O桥去CPU放羊
一天,他看到有一个数据读,头也不回地跑到主存大声喊:“读来了!读来了!快缓存啊!”主存一收到数据读的信号,急忙把一块数据拿出来放到总线上,然后往L3、L2、L1层层缓存,边准备边喊:“不要怕,孩子,SRAM会帮你的!”
然而加载单元读了一个数据就停了,接下来是一连串的cache miss。放羊娃哈哈大笑:“真有意思,缓存了这么多,性能还不如不缓存!”SRAM们瞥了他一眼,什么都没说
第二天,放羊娃又看到一个数据读,于是故技重施,勤勤恳恳的RAM们又从头做了一遍缓存,可加载单元还是读了一个数据就走了
放羊娃笑得直不起腰:“哈哈!你们又浪费性能了!哈哈!”SRAM们对放羊娃一而再再而三地违反局部性十分生气,一段时间后,纷纷按照LFU策略把两次缓存的行清了出去。
过了几天,放羊娃真的看到了一连串步长为1的数据读,并且恰好紧挨着之前的两个数据读。放羊娃害怕极了,拼命地对着SRAM喊,“读来了!大量的读来了!快救命啊!和之前的是一整片!”
SRAM们听到他的喊声,只冷冷地对他说:“已经清掉了”,没有cache去帮他,就连主存也说“去磁盘读吧”。结果放羊娃为此浪费了数十万个时钟周期。
这个故事告诉我们,程序员写的程序应当具有良好的局部性,比如不要跳着访问数组