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 );