- 論壇徽章:
- 0
|
static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
//如果size為常量,比如以這種方式調(diào)用kmalloc(32,GFP_KERNEL);
//__builtin_constant_p來(lái)確定size是否為常量
if (__builtin_constant_p(size))
{ //找到合適的大小的普通高速緩沖區(qū)索引
int i = 0;
#define CACHE(x) \
if (size <= x) \
goto found; \
else \
i++;
#include <linux/kmalloc_sizes.h>
#undef CACHE
return NULL;
found:
//獲取普通高速緩沖區(qū)描述符指針
cachep = malloc_sizes.cs_cachep;
ret = kmem_cache_alloc_notrace(cachep, flags);
return ret;
}
//如果size為變量,則調(diào)用__kmalloc分配對(duì)象
return __kmalloc(size, flags);
}
在/linux/kmalloc_sizes.h中,定義了一些宏,如下:
……
CACHE(256)
CACHE(512)
……
所以宏展開(kāi)后變成:
……
if(32<=256)
goto found;
else
i++;
if(32<=512)
goto found;
else
i++;
……
如果size為變量,比如以這種方式調(diào)用kmalloc(a,GPF_KERNEL);
則獲取高速緩沖區(qū)描述符的索引的代碼如下:
struct cache_sizes *csizep = malloc_sizes;
while (size > csizep->cs_size)
csizep++;
到底加入常量編譯器特性有多少性能提高呢?
只好用個(gè)demo來(lái)測(cè)試了:
Demo1代表常量處理的過(guò)程:
int i=0;
#define CACHE(x) \
if (1024<= x) \ //1024代表常量size
goto found; \
else \
i++;
CACHE(32)
CACHE(64)
CACHE(96)
CACHE(12
CACHE(192)
CACHE(256)
CACHE(512)
CACHE(1024)
CACHE(204
found:
printf("i=%d\n",i);
return 0;
Demo2代表變量處理的過(guò)程:
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)
//編譯器優(yōu)化的結(jié)果就是:if else判斷被優(yōu)化成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)
//獲取數(shù)組a的開(kāi)始地址
movl $a, -8(%ebp)
.L2:
//把數(shù)組a中某元素的地址賦給edx
movl -8(%ebp), %edx
//把變量b的值賦給eax
movl -4(%ebp), %eax
比較數(shù)組a中的元素與b值的大小
cmpl (%edx), %eax
jg .L4
jmp .L3
.L4:
//獲取數(shù)組的下一個(gè)元素
leal -8(%ebp), %eax
addl $4, (%eax)
jmp .L2
.L3:
。。。。。。//打印代碼略去
所以demo1只用了14條指令(每次遞增2條指令)來(lái)獲取高速緩沖區(qū)的索引。
Demo2每次比較用7條指令*比較次數(shù)7=49條指令來(lái)獲取高速緩沖區(qū)的索引。 |
|