kmalloc中的常量参数优化处理

static __always_inline void *kmalloc(size_t size, gfp_t flags)

{

      

    //如果size为常量,比如以这种方式调用kmalloc(32GFP_KERNEL)

       //__builtin_constant_p来确定size是否为常量

       if (__builtin_constant_p(size))

{   //找到合适的大小的普通高速缓冲区索引

              int i = 0;

#define CACHE(x) /

                   if (size <= x) /

                         goto found; /

                   else /

                         i++;

#include <linux/kmalloc_sizes.h>

#undef CACHE

              return NULL;

found

        //获取普通高速缓冲区描述符指针

              cachep = malloc_sizes[i].cs_cachep;

              ret = kmem_cache_alloc_notrace(cachep, flags);

              return ret;

       }

    //如果size为变量,则调用__kmalloc分配对象

       return __kmalloc(size, flags);

}

 

/linux/kmalloc_sizes.h中,定义了一些宏,如下:

       ……

CACHE(256)

       CACHE(512)

    ……

所以宏展开后变成:

……

if(32<=256)

   goto found

else

   i++

if(32<=512)

   goto found

else

   i++

……

 

 

如果size为变量,比如以这种方式调用kmalloc(a,GPF_KERNEL)

则获取高速缓冲区描述符的索引的代码如下:

struct cache_sizes *csizep = malloc_sizes

while (size > csizep->cs_size)

              csizep++

 

到底加入常量编译器特性有多少性能提高呢:

只好用个demo来测试了:

Demo1代表常量处理的过程:        

int i=0;

    #define CACHE(x) /

          if (1024<= x) /   //1024代表常量size

              goto found; /

          else /

              i++;

 

     CACHE(32)

     CACHE(64)

     CACHE(96)

     CACHE(128)

     CACHE(192)

     CACHE(256)

     CACHE(512)

     CACHE(1024)

     CACHE(2048)

found:

     printf("i=%d/n",i);

  return 0;

 

Demo2代表变量处理的过程:

   int a[10]={32,64,96,128,256,512,1024,2048,};

   int b=1024;//b代表变量size

   int* p=a;

 

   while(b>*p)

       p++;

 

   printf("%d/n",*p);

 

这两段demo都用gcc S demo1.c demo2.c处理下生成汇编文件,如下:

Demo1.s

main:

     pushl    %ebp

     movl %esp, %ebp

     subl $8, %esp

     andl $-16, %esp

     movl $0, %eax

     subl %eax, %esp

     //i=0

     movl $0, -4(%ebp)

     //i地址赋给寄存器eax

     leal -4(%ebp), %eax

     //递增i的值

incl (%eax)

     leal -4(%ebp), %eax

     incl (%eax)

     leal -4(%ebp), %eax

     incl (%eax)

     leal -4(%ebp), %eax

     incl (%eax)

     leal -4(%ebp), %eax

     incl (%eax)

     leal -4(%ebp), %eax

     incl (%eax)

     leal -4(%ebp), %eax

     incl (%eax)

 //编译器优化的结果就是:if else判断被优化成7次直接的i++

.L3:

    。。。。。。//打印代码略去

Demo2.s

main:

     pushl    %ebp

     movl %esp, %ebp

     subl $8, %esp

     andl $-16, %esp

     movl $0, %eax

     subl %eax, %esp

     //局部变量b赋值为1024

     movl $1024, -4(%ebp)

     //获取数组a的开始地址

movl $a, -8(%ebp)

.L2:

     //把数组a中某元素的地址赋给edx

     movl -8(%ebp), %edx

    //把变量b的值赋给eax

     movl -4(%ebp), %eax

     比较数组a中的元素与b值的大小

     cmpl (%edx), %eax

     jg   .L4

     jmp  .L3

.L4:

     //获取数组的下一个元素

     leal -8(%ebp), %eax

addl $4, (%eax)

     jmp  .L2

.L3:

   。。。。。。//打印代码略去

所以demo1只用了14条指令(每次递增2条指令)来获取高速缓冲区的索引。

Demo2每次比较用7条指令*比较次数7=49条指令来获取高速缓冲区的索引。

你可能感兴趣的:(kmalloc中的常量参数优化处理)