1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| #include<stdio.h>
int zend_mm_small_size_to_bit(int size){ return (__builtin_clz(size) ^ 0x1f) + 1; }
int php(int size){ unsigned int t1, t2;
if (size <= 64) { return (size - !!size) >> 3; } else { t1 = size - 1; t2 = zend_mm_small_size_to_bit(t1) - 3; t1 = t1 >> t2; t2 = t2 - 3; t2 = t2 << 2; return (int)(t1 + t2); } }
int my0(int size){ unsigned t1,high,offset; t1 = size-1; high = zend_mm_small_size_to_bit(t1)-1; offset = (t1 - (1<<high) + (1 << (3+high-5))) >> (3+high-5); return offset + ((high-4)<<2)-1; }
int my1(int size){ unsigned t1,high,offset; t1 = size-1; high = zend_mm_small_size_to_bit(t1)-1; offset = (t1 - (1<<high) + (1 << (high-2))) >> (high-2); return offset + ((high-4)<<2)-1; }
int my2(int size){ unsigned t1,high,offset; t1 = size-1; high = zend_mm_small_size_to_bit(t1)-3; offset = (t1 - (1<<(high+2)) + (1 << (high))) >> (high); return offset + ((high-2)<<2)-1; }
int my3(int size){ unsigned t1,high,offset; t1 = size-1; high = zend_mm_small_size_to_bit(t1)-3; offset = ((t1 - (1<<(high+2))) >> (high)) + 1; return offset + ((high-2)<<2)-1; }
int my4(int size){ unsigned t1,high,offset; t1 = size-1; high = zend_mm_small_size_to_bit(t1)-3; offset = ((t1 - (1<<(high+2))) >> (high)); return offset + ((high-2)<<2); }
int my5(int size){ unsigned t1,high,offset; t1 = size-1; high = zend_mm_small_size_to_bit(t1)-3; offset = (t1 >> high) -(1<<2) ; return offset + ((high-2)<<2); }
int my6(int size){ unsigned t1,high,offset; t1 = size-1; high = zend_mm_small_size_to_bit(t1)-3; offset = (t1 >> high); return offset + ((high-3)<<2); }
int main(){
printf("%d\n",my6(2600)); printf("%d\n",php(2600)); return 1; }
|
small_index在8-64之前按8递增,所以直接除8即可(考虑size==0的情况,!!0==1)
对于t1和t2的我理解是:t1表示区间偏移,t2区间。整体上区间可以划分位(1-64],(64,128],(128,256],(256,512],(512,1024],(1024,2048],(2048,3072]
第一个区间按8划分偏移,第二个区间按16划分偏移,,,,
可以看出来是有规律的,需要申请的内存大小可能落在其中一个区间里面,区间里面在细分。
如果要判断落在那个区间,直觉上要看size最高位的1落在哪个地方,举个例子如果落在2^6上,则一定在(64,128]上(假设已经排除了<=64)。
最高位用bsr算,则为第7bit位,我们需要再算它在这个区间上的偏移,需要先减去前一个区间最大的binsize,然后再除以现区间的划分size。