Linux内核快速处理路径尽量多用kmem_cache而慎用kmalloc

题目是一个典型 《Effective C++》 的风格 。
事情是这样的 , 我大致说一下 。
我在开发一个Netfilter模块 , 在PREROUTING匹配一些数据包 , 显而易见 , 都能想到使用哈希表hlist作为数据结构的容器 , 其中装有下面的结构体:
struct item {struct hlist_node hnode;char padding[16];};生成item的时候 , 我先用 kmalloc 接口分配内存:
【Linux内核快速处理路径尽量多用kmem_cache而慎用kmalloc】item_nd = (struct item *)kmalloc(sizeof(struct item), GFP_KERNEL);然后我用hlist_add/del接口将分配好的结构体插入到hlist中 。
仅仅为了测试是否会宕机 , 所以我的所有的数据结构的hash值均是一样的 , 这样插入200个项的话 , 它们会hash冲突 , 从而仅仅添加到同一个hlist链表中 , 这样整个匹配过程就退化成了遍历200个项的链表 。
虽然是万恶的遍历操作 , 但200个项一切还OK , 性能几乎是无损的 , 无论是吞吐 , 还是pps 。
这个时候 , 我想扩充一些功能 , 于是乎为item结构体增加了一个字段:
struct item {struct hlist_node hnode;char padding[16];void *private;};仅仅增加了一个private , 其它均和之前完全一致 , 同样的200个项插入同一条hlist , 同样遍历 , 吞吐和pps下降达到15%~20%!
为什么增加了一个指针变量 , 就出现了如此巨大的性能差异?!


    推荐阅读