Linux中仅含分号的prefetch空函数体如何使用?
Linux内核中
prefetch空函数的作用与用法 Linux内核include/linux/list.h里定义的这个空实现的prefetch函数,是CPU数据预取功能的通用封装:
static inline void prefetch(const void *x) {;}
它的空函数体是默认的兜底实现——针对x86、ARM这类支持预取指令的CPU架构,内核会通过条件编译替换成带汇编预取指令的实际实现,提前把即将访问的数据加载到CPU缓存,降低内存访问延迟;不支持预取的架构上,这个空调用会被编译器优化掉,不会产生额外开销。
再看它在list_for_each_entry宏里的具体用法:
#define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ prefetch(pos->member.next), &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member))
这里利用了C语言逗号运算符的特性:先执行左侧表达式,再执行右侧,最终返回右侧表达式的结果。放在for循环的条件判断部分,逻辑是:
- 每次检查循环终止条件
&pos->member != (head)之前,先调用prefetch预取下一个链表节点的内存数据 - 实际控制循环是否继续的还是右侧的终止条件
这么做的核心目的是隐藏内存访问延迟:在CPU执行当前循环体的间隙,提前把下一个要访问的链表节点加载到缓存,当循环进入下一次迭代时,数据已经在缓存中,能显著提升长链表遍历的效率。
内容的提问来源于stack exchange,提问作者Chan Kim
相关产品推荐
相关产品推荐

