kmem_cache slab allocator linux kernel
작은 구조체를 빈번 할당 할 때 사용하면 유용하다. 한 페이지가 보통 4kb니까 4kb에 얼라인 되도록 하는 편이 캐시 미스도 덜 나고 좋을 듯.
성능은 대략 이렇다.
S5PC100 Cortex-A8 633Mhz
SLAB = 888us SLUB = 768us
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/syscalls.h>
#include <linux/kallsyms.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
struct slab_object
{
unsigned int id;
char name[10];
char depart[10];
unsigned int score;
struct slab_object *next;
};
static inline long myclock()
{
struct timeval my_time;
do_gettimeofday(&my_time);
return my_time.tv_usec;
}
<div>void test_func(void)
{
struct kmem_cache *my_cache;
void *my_object_head;
struct slab_object *temp_object;
struct slab_object *current_object;
int i;
my_cache = kmem_cache_create("slab_object", sizeof(struct slab_object), 0, SLAB_HWCACHE_ALIGN, NULL);
printk("kmem_cache name = %s\n", kmem_cache_name(my_cache));
printk("kmem_cache size = %d\n", kmem_cache_size(my_cache));
printk("size of = %d\n", sizeof(struct slab_object));
my_object_head = kmem_cache_alloc(my_cache, GFP_KERNEL);
current_object = (struct slab_object *)my_object_head;
for (i = 1; i < 200; i++) {
temp_object = kmem_cache_alloc(my_cache, GFP_KERNEL);
current_object->next = temp_object;
current_object = current_object->next;
}
current_object = my_object_head;
temp_object = current_object;
for (i = 0; i < 200; i++) {
if (current_object) {
kmem_cache_free(my_cache, current_object);
} else {
printk("free error!\n");
}
temp_object = temp_object->next;
current_object = temp_object;
}
if (my_cache) kmem_cache_destroy(my_cache);
return;
}
int __init m_init( void )
{
long st, et;
printk("init!\n");
st = myclock();
test_func();
et = myclock();
printk("test end!, total_time = %ldus\n", et - st);
return 0;
}
void __exit m_exit( void )
{
printk("exit!\n");
}
module_init( m_init );
module_exit( m_exit );