转载:http://www.kernelchina.org/node/1050
linux的list实现之中有如下东东:
#define
list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)
在遍历过程中使用了prefetch,其功能是数据的预先读取。当你确认后继续要读取某内存的信息的时候,可以采用prefetch将这一块数据读 取到cache之中,以便后继快速访问。我的理解是条件不止这些,如果后继读取的内容仅仅被访问一次,那么是否prefetch也就没有意义了。后继访问 的内存单元多次被读写才有意义。对于上述的list操作,在循环内部往往还会访问next指向的structure的内容,因此访问多次是可以期待的。
除了list之外很容易理解,array中的相邻的邻居,在遍历的时候也是可以prefetch的。prefetch的一个单元常常是一个cacheline的大小。
linux的prefetch的API描述如下
/*
prefetch(x) attempts to pre-emptively get the memory pointed to by
address "x" into the CPU L1 cache. prefetch(x) should not
cause any kind of exception, prefetch(0) is
specifically ok.
prefetch() should be defined by the architecture, if not, the
#define below provides a no-op define.
There are 3 prefetch() macros:
prefetch(x) - prefetches the cacheline
at "x" for read
prefetchw(x) - prefetches the cacheline at "x" for
write
spin_lock_prefetch(x) - prefetches the spinlock *x for taking there
is also PREFETCH_STRIDE which is the architecure-prefered
"lookahead" size for prefetching streamed operations.
*/
看来无论读写都需要prefetch,我看了一下,多数平台这几个宏定义实现是一样的。(有什么细微差别不详,都是把数据写到cache中,等待高人指点)
在更加high level的层面也有prefetch的概念,例如OS之中的disk cache。Windows在启动的时候以提供prefetch功能预先加载可能会被后继启动的应用使用到的数据。
软件也可以采用类似手段,将后继会用到的数据在启动的时候预先读取到内存中。
相关概念在传统的数据结构课程之中有所缺失。
【参考】
http://en.wikipedia.org/wiki/Cache