亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

php中small內存規格的計算(代碼示例)

2020-03-22 17:55:41
字體:
來源:轉載
供稿:網友
本篇文章給大家帶來的內容是關于php中small內存規格的計算(代碼示例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

 

small內存分配計算bin_num

在PHP源碼中,有一段對small內存規格的計算,具體在Zend/zend_alloc.c的zend_mm_small_size_to_bin函數中,其目的是傳入一個size,計算對應的規格。見代碼:

if (size = 64) { /* we need to support size == 0 ... */ 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);}

可以看出,這段代碼中分為兩種情況進行討論:

1、size小于等于64的情況;

2、size大于64的情況;

下面我們對這兩種情況詳細分析下。

對于size小于等于64的情況

看ZEND_MM_BINS_INFO這個宏知道當size小于等于64的情況是一個等差數列,遞增8,所以使用size除以8就行(源碼中是右移3位)size 3

但是要考慮到size等于8、16等的情況,所以為 (size - 1) 3

然后要考慮到為0的情況,所以源碼中對于-1的處理是!!size,當size為0的情況!!0 = 0。所以當size為0的情況就把-1轉換成了-0,最終有了源碼中的表達式 (size - !!size) 3

對于size大于64的情況
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);
初始懵逼

初看這個代碼,容易一臉懵逼,這些t1 t2 都是啥啊

不過不用怕,我們一點點來分析

步驟分析
/* num, size, count, pages */#define ZEND_MM_BINS_INFO(_, x, y)  _( 0, 8, 512, 1, x, y)  _( 1, 16, 256, 1, x, y)  _( 2, 24, 170, 1, x, y)  _( 3, 32, 128, 1, x, y)  _( 4, 40, 102, 1, x, y)  _( 5, 48, 85, 1, x, y)  _( 6, 56, 73, 1, x, y)  _( 7, 64, 64, 1, x, y)  _( 8, 80, 51, 1, x, y)  _( 9, 96, 42, 1, x, y)  _(10, 112, 36, 1, x, y)   _(11, 128, 32, 1, x, y)  _(12, 160, 25, 1, x, y)   _(13, 192, 21, 1, x, y)  _(14, 224, 18, 1, x, y)   _(15, 256, 16, 1, x, y)  _(16, 320, 64, 5, x, y)   _(17, 384, 32, 3, x, y)  _(18, 448, 9, 1, x, y)   _(19, 512, 8, 1, x, y)  _(20, 640, 32, 5, x, y)  _(21, 768, 16, 3, x, y)  _(22, 896, 9, 2, x, y)   _(23, 1024, 8, 2, x, y)  _(24, 1280, 16, 5, x, y)  _(25, 1536, 8, 3, x, y)  _(26, 1792, 16, 7, x, y)   _(27, 2048, 8, 4, x, y)  _(28, 2560, 8, 5, x, y)  _(29, 3072, 4, 3, x, y)#endif /* ZEND_ALLOC_SIZES_H */

size = size - 1; 這個是邊界情況,跟前面一樣,后面出現的size暫且都認為已近減一了

假設不看這個源碼,我們要實現在ZEND_MM_BINS_INFO中找到對應的bin_num

由ZEND_MM_BINS_INFO得知后續的增加4個為一組,分別為

2^4, 2^5, 2^6...

有了這個分組信息的話,我們要找siez對應的bin_num

找到這個size屬于哪一組

并且size在組內的偏移是多少

計算組的起始位置

那現在問題轉換成了上面3個小問題,我們一個一個來解決

找到size屬于哪一組

最簡單的辦法就是比大小是吧,可以使用if...else 來一個一個比,但是顯然php源碼不是這樣干的,那我們還有什么其它的辦法呢?

我們看十進制看不出來什么名堂,就把這些值轉成二進制看看吧

64 | 100 000080 | 101 000096 | 110 0000112 | 111 0000128 | 1000 0000160 | 1010 0000192 | 1100 0000224 | 1110 0000256 | 1 0000 0000320 | 1 0100 0000384 | 1 1000 0000448 | 1 1100 0000.....

我們看下上面的二進制,會發現每組的內的二進制長度相等,并且后面每個都比前面多一位

那就是說我們可以計算二進制的長度來決定它的分組,那么二進制的長度又是啥呢,其實就是當前二進制的最高位為1的位數

那么問題又轉換成了求二進制中最高位的1的位數

下面給出php源碼的解法,這里暫時不對其解析,只要知道它返回的是二進制中最高位的1的位數

int n = 16;if (size = 0x00ff) {n -= 8; size = size 8;}if (size = 0x0fff) {n -= 4; size = size 4;}if (size = 0x3fff) {n -= 2; size = size 2;}if (size = 0x7fff) {n -= 1;}return n;

假設我們申請的size為65,那么這里的n返回7

計算size在組內的偏移量

這個簡單,直接用size減去每組的起始siez大小然后除以當前組內的差值(16、32、64...)即可,也就是(size-64)/16 (size-128)/32 (size-256)/64

現在來看看上一步中的返回的值,每個組分別是7、8、9...,那么我們現在來看看這樣的數據怎么計算組內的偏移量

(size - 2^4 * 4) / 16 = size / 2^4 - 4(size - 2^5 * 4) / 32 = size / 2^5 - 4 (size - 2^6 * 4) / 64 = szie / 2^6 - 4

那是不是可以用7、8、9減去3得到4、5、6,這樣我們就可以根據它在哪一組的信息得到當前組的差值(16、32、64...)

當size為65時,偏移量是不是就是

(64-64) / 2^4 = 0
計算組的起始位置

現在我們有了偏移量的信息,假定我們分組是1、2、3

那是不是就是用最高位的1的位數減去6就可以得到分組信息了

得到分組信息之后,怎么知道每組的起始位置呢

我們知道起始位置分別是8、12、16...它也是一個等差數列,就是4n+4

我們在看看size=65的那個例子

計算的偏移量是0

計算的起始位置是4*1 + 4 = 8

所以當size=65的bin_num就是起始位置加上偏移量 8 + 0 = 8

我們再看一個size=129的例子

二進制中最高位的1的位數為8

然后用8減去3得到5

(129 - 1 - 32 * 4) / 64 = 0

偏移量是

計算起始位置是 4 * 2 + 4 = 12

兩者相加就是 12 + 0 = 0

size=193

二進制中最高位的1的位數為8

(193 - 1 - 32 * 4) / 64 = 2

偏移量是

計算起始位置是 4 * 2 + 4 = 12

兩者相加就是 12 + 2 = 14

size=1793

二進制中最高位的1的位數為11

(1793 - 1 - 256 * 4) / 256 = 3

偏移量是

計算起始位置是 4 * 5 + 4 = 24

兩者相加就是 24 + 3 = 27

代碼分析php實現代碼
1 t1 = size - 1;2 t2 = zend_mm_small_size_to_bit(t1) - 3;3 t1 = t1 t2;4 t2 = t2 - 3;5 t2 = t2 2;6 return (int)(t1 + t2);
第一行

t1 = size - 1;

是為了考慮size為64、128...這些邊界情況

第二行

t2 = zend_mm_small_size_to_bit(t1) - 3;

這里調用了zend_mm_small_size_to_bit這個函數,我們看看這個函數

/* higher set bit number (0- N/A, 1- 1, 2- 2, 4- 3, 8- 4, 127- 7, 128- 8 etc) */int n = 16;if (size = 0x00ff) {n -= 8; size = size 8;}if (size = 0x0fff) {n -= 4; size = size 4;}if (size = 0x3fff) {n -= 2; size = size 2;}if (size = 0x7fff) {n -= 1;}return n;

注釋我們就知道這個函數是用來返回當前size二進制中最高位1的位數,具體的做法呢其實就是二分法

我們通過zend_mm_small_size_to_bit這個函數獲取了size二進制中最高位1的位數,那么這個 -3 是什么神奇的操作呢

(size - 2^4 * 4) / 16 = size / 2^4 - 4 (size - 2^5 * 4) / 32 = size / 2^5 - 4 (size - 2^6 * 4) / 64 = szie / 2^6 - 4

這里獲取二進制的位數是7、8、9...通過 -3 的操作來獲取相應的 4、5、6...

上問的分析中提到,我們計算size在組內的偏移量的公式

第三行

t1 = t1 t2;

把t1右移t2位,這又是什么神奇的操作?

這里我們把最后計算bin_num的數學公式給寫出來,它是等于每組的起始位置加上組內的偏移量

binnum = (4n + 4) + (size / 2^n - 4)binnum = 4n + size / 2^n

所以第三行的意思我們就知道了,就是size右移2^n次方為

第四行

t2 = t2 - 3;

這個好理解,可以參照上文得到每組的起始位置的方法

第五行

t2 = t2 2;

我們再看看bin_num的計算公式

binnum = (4n + 4) + (size / 2^n - 4)binnum = 4n + size / 2^n

那么這行就好理解了,就是計算每組的起始位置4n對吧,左移兩位就是乘以4

第六行

return (int)(t1 + t2);

這行沒啥說的,就是返回了一個int類型的bin_num

以上就是php中small內存規格的計算(代碼示例)的詳細內容,PHP教程

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩免费黄色av| 亚洲欧美三级在线| 亚洲无限av看| 影音先锋日韩有码| 奇米影视亚洲狠狠色| 97视频免费看| 日韩精品在线播放| 亚洲精品www久久久| 欧美视频在线免费看| 成人黄色影片在线| 久久视频这里只有精品| 欧美成人在线免费| 亚洲精品电影网在线观看| 亚洲网址你懂得| 久久天天躁狠狠躁夜夜躁| 欧美精品videossex性护士| 日本久久久久久| 亚洲自拍偷拍一区| 亚洲第一网中文字幕| 日韩一区二区三区国产| 久久青草精品视频免费观看| 色综合久久精品亚洲国产| 欧美最猛性xxxxx亚洲精品| 国产在线观看精品| 中文亚洲视频在线| 亚洲人成免费电影| 亚洲人成绝费网站色www| 国产99久久精品一区二区永久免费| 国产精品爽爽爽爽爽爽在线观看| 亚洲理论片在线观看| 中文字幕在线观看亚洲| 国产精彩精品视频| 亚洲大胆人体av| 国色天香2019中文字幕在线观看| 国产精品一区二区久久国产| 韩国国内大量揄拍精品视频| 欧美高清不卡在线| 亚洲国产精品va在线看黑人动漫| 精品成人乱色一区二区| 亚洲欧美在线播放| 夜夜躁日日躁狠狠久久88av| 久久人人97超碰精品888| 久久久久久久av| 亚洲福利在线观看| 夜夜嗨av色综合久久久综合网| 久久欧美在线电影| 精品无人区乱码1区2区3区在线| 久久69精品久久久久久国产越南| 26uuu另类亚洲欧美日本老年| 欧美在线视频免费观看| 亚洲成人a级网| 日本精品免费观看| 岛国av一区二区在线在线观看| 亚洲xxx视频| 国产一区视频在线| 亚洲аv电影天堂网| 中文字幕亚洲国产| 国产亚洲精品久久久久久| 久久久999成人| 日韩高清av一区二区三区| 亚洲综合精品伊人久久| 国产精品久久久久影院日本| 国产美女91呻吟求| 欧洲午夜精品久久久| 国产欧美在线播放| www.美女亚洲精品| 国产一区二区日韩精品欧美精品| 久久久久久久91| 精品国产乱码久久久久久虫虫漫画| 欧美富婆性猛交| 555www成人网| 欧美在线精品免播放器视频| 日韩精品极品视频| 91国产视频在线播放| 国产69精品久久久久久| 日韩免费观看在线观看| 亚洲аv电影天堂网| 国产日韩中文在线| 欧美高清视频在线播放| 最近中文字幕2019免费| 激情成人在线视频| 国产精品免费在线免费| 欧美贵妇videos办公室| 91久久精品在线| 92版电视剧仙鹤神针在线观看| 亚洲精品视频播放| 亚洲www在线| 亚洲网在线观看| 国产精品入口福利| 国产精品一区二区电影| 俺去亚洲欧洲欧美日韩| 欧美亚洲午夜视频在线观看| 九九九热精品免费视频观看网站| 美乳少妇欧美精品| 精品视频9999| 精品人伦一区二区三区蜜桃免费| 亚洲深夜福利在线| 91在线视频免费| 成人福利视频在线观看| 7m第一福利500精品视频| 国产精品久久久久免费a∨大胸| **欧美日韩vr在线| 久久久久久久久中文字幕| 国产精品中文字幕在线| 大伊人狠狠躁夜夜躁av一区| 国产成人高潮免费观看精品| 日本高清视频精品| 日韩一区在线视频| 国产欧美精品在线| 中文字幕日本精品| 亚洲成人a**站| 亚洲视频在线看| 992tv成人免费视频| 久久国产精品视频| 91禁外国网站| 92裸体在线视频网站| 中文字幕无线精品亚洲乱码一区| 亚洲午夜久久久久久久| 精品久久香蕉国产线看观看亚洲| 欧美激情精品久久久久久蜜臀| 这里只有精品在线播放| 亚洲精品日产aⅴ| 午夜精品久久久久久久99黑人| 欧美性猛交视频| 久久久久久久国产| 亚洲国产欧美在线成人app| 国产日韩欧美在线| 高清欧美性猛交xxxx黑人猛交| 日韩综合视频在线观看| 97超级碰碰人国产在线观看| 91sao在线观看国产| 成人综合国产精品| 久久视频这里只有精品| 久久手机免费视频| 欧美成人免费全部观看天天性色| 亚洲国产精品一区二区久| 国产精品日韩av| 亚洲黄色成人网| 欧美激情久久久| 国产精品电影一区| 亚洲国产天堂久久综合网| 中文字幕精品av| 国产精品mp4| 日韩在线欧美在线国产在线| 国产精品美女www爽爽爽视频| 影音先锋日韩有码| 亚洲第一黄色网| 亚洲精品一区二三区不卡| 97国产精品久久| 一区二区三区视频免费| 777午夜精品福利在线观看| 日韩精品免费综合视频在线播放| 久久视频国产精品免费视频在线| xvideos成人免费中文版| 亚洲图片欧美午夜| 久久天天躁狠狠躁夜夜爽蜜月| 国产一区二区三区在线观看网站| 北条麻妃在线一区二区| 欧美一级在线亚洲天堂| 欧美特黄级在线| 午夜精品在线观看| 国产精品一区二区久久精品| 97av在线影院| 国产亚洲在线播放|