深度學(xué)習(xí) Caffe 內(nèi)存管理機(jī)制理解

本文是作者原創(chuàng)嘹裂,如有理解錯(cuò)誤妄壶,懇請(qǐng)大家指出,如需引用寄狼,請(qǐng)注明出處丁寄。

Blob內(nèi)存管理分析

在caffe的分層結(jié)構(gòu)中,Blob充當(dāng)了內(nèi)存管理的角色泊愧,屏蔽了上層邏輯代碼對(duì)于數(shù)據(jù)的申請(qǐng)釋放的感知伊磺,同時(shí)也屏蔽了底層設(shè)備對(duì)上層邏輯的影響,本文主要分析Blob的管理機(jī)制和實(shí)際內(nèi)存申請(qǐng)單元SyncedMemory 的機(jī)制删咱。
首先我們看一下Blob和SyncedMemory的關(guān)系屑埋,類(lèi)圖如下:

blob_class.jpg

實(shí)際上整個(gè)Blob的實(shí)現(xiàn)就是在SyncedMemory上封裝了一層,所以首先需要分析一下SyncedMemory的實(shí)現(xiàn)機(jī)制痰滋。

SyncedMemory的實(shí)現(xiàn)機(jī)制

SyncedMemory的目的是為了屏蔽上層代碼對(duì)不同硬件設(shè)備的內(nèi)存分配的感知摘能,同時(shí)隱藏了CPU和GPU之間的同步過(guò)程。同時(shí)即寡,SyncedMemory實(shí)現(xiàn)時(shí)徊哑,采用的是 “l(fā)azy”的模式,就是內(nèi)存的實(shí)際申請(qǐng)時(shí)機(jī)是在第一次使用時(shí)進(jìn)行的聪富。有了大體的了解,下面我們來(lái)詳細(xì)分析一下著蟹。
下面是SyncedMemory 提供的一組接口墩蔓,

名稱(chēng) 功能
cpu_data() 獲取CPU數(shù)據(jù)指針
gpu_data() 獲取GPU數(shù)據(jù)指針

實(shí)現(xiàn)的代碼如下:

const void* SyncedMemory::cpu_data() {
  to_cpu();
 return (const void*)cpu_ptr_;
}

const void* SyncedMemory::gpu_data() {
#ifdef USE_CUDA
  to_gpu();
  return (const void*)gpu_ptr_;
#else
  NO_GPU;
  return NULL;
#endif  // USE_CUDA
}

可以看出梢莽,每次調(diào)用接口時(shí),都會(huì)有 to_cpu() 和 to_gpu() 的操作,那么這兩個(gè)操作是什么作用呢奸披,我們先看下SyncedMemory中的一些關(guān)鍵參數(shù):

名稱(chēng) 功能
cpu_ptr_ cpu數(shù)據(jù)指針
gpu_ptr_ gpu數(shù)據(jù)指針
size_ 當(dāng)前SyncedMemory需要維護(hù)的數(shù)據(jù)個(gè)數(shù)
head_ 當(dāng)前 SyncedMemory處于的狀態(tài)

前三個(gè)都比較好理解昏名,最后一個(gè)比較特殊,它維護(hù)的是 SyncedMemory 當(dāng)前的狀態(tài)阵面,分為 UNINITIALIZED轻局,HEAD_AT_GPU,HEAD_AT_CPU 样刷,SYNCED 四中狀態(tài)÷仄耍現(xiàn)在介紹一下具體的流程,當(dāng)?shù)谝淮握{(diào)用 to_cpu()時(shí)置鼻, head_處于UNINITIALIZED狀態(tài)镇饮,那么系統(tǒng)會(huì)調(diào)用 CPU的申請(qǐng)內(nèi)存的方式去獲得內(nèi)存區(qū)域,之后設(shè)置 head_ = HEAD_AT_CPU ,如果中間過(guò)程沒(méi)有GPU設(shè)備則不會(huì)有狀態(tài)變動(dòng)箕母,如果中間有代碼調(diào)用了 to_gpu() ,則會(huì)發(fā)現(xiàn) head_處于 HEAD_AT_CPU 狀態(tài)储藐,此時(shí)會(huì)調(diào)用同步函數(shù),將數(shù)據(jù)從CPU同步到GPU嘶是, 之后如果又回到CPU上钙勃,則同樣會(huì)發(fā)現(xiàn) head_ 處于HEAD_AT_GPU的狀態(tài),那么又會(huì)調(diào)用相應(yīng)的同步代碼聂喇,將數(shù)據(jù)同步回CPU辖源,通過(guò) head_這樣一個(gè)狀態(tài)參數(shù)屏蔽了GPU和CPU間的申請(qǐng)和切換的不同。

所以上層業(yè)務(wù)只需要知道當(dāng)前自己需要的是CPU還是GPU的數(shù)據(jù)授帕,然后調(diào)用不同的接口同木,就可以完成數(shù)據(jù)獲取的操作。

Blob的實(shí)現(xiàn)分析

了解了SyncedMemory的實(shí)現(xiàn)跛十,再來(lái)看Blob 就較為簡(jiǎn)單了彤路,它僅僅做了一些上層的管理邏輯,向外界提供了幾個(gè)關(guān)鍵的接口:

名稱(chēng) 功能
cpu_data() 獲取CPU數(shù)據(jù)指針芥映,不能改變數(shù)據(jù)內(nèi)容
mutable_cpu_data() 獲取CPU數(shù)據(jù)指針洲尊,可以改變數(shù)據(jù)內(nèi)容
gpu_data() 獲取GPU數(shù)據(jù)指針,不能改變數(shù)據(jù)內(nèi)容
mutable_gpu_data() 獲取GPU數(shù)據(jù)指針奈偏,可以改變數(shù)據(jù)內(nèi)容
Reshape() 調(diào)整數(shù)據(jù)的維度信息

前四個(gè)就是對(duì) SyncedMemory 的 cpu_data() 和 gpu_data()的封裝,只需要確保每次獲取數(shù)據(jù)前都調(diào)用相對(duì)的 to_cpu 或者 to_gpu就可以了坞嘀。對(duì)于最后一個(gè)Reshape函數(shù),主要是為了調(diào)整維度信息惊来,同時(shí)可能是出于適配多種數(shù)據(jù)格式的目的丽涩,所以提供3個(gè)重載函數(shù),如下:

void Blob::Reshape(const int num, const int channels,const int height, const int width);
void Blob::Reshape(const BlobShape& shape) ;
void Blob::Reshape(const vector<int>& shape);

前兩個(gè)重載函數(shù)僅僅進(jìn)行了數(shù)據(jù)格式的轉(zhuǎn)換,然后調(diào)用第三個(gè)函數(shù)矢渊,所以 void Blob::Reshape(const vector<int>& shape);才是實(shí)際的執(zhí)行者继准,這里需要介紹一下Blob里面較為關(guān)鍵的幾個(gè)參數(shù):

名稱(chēng) 功能
data_ 數(shù)據(jù)的實(shí)際存儲(chǔ)位置
shape_data_ 數(shù)據(jù)的維度信息存儲(chǔ)位置(NCHW)
capacity_ 當(dāng)前數(shù)據(jù)塊的大小
count_ reshape后的數(shù)據(jù)塊的大小

閱讀代碼不難發(fā)現(xiàn),cout_中所存儲(chǔ)的就是所有維度的的乘積矮男,也就是當(dāng)前要reshape到的數(shù)據(jù)大小移必,整個(gè)的reshape 過(guò)程如下:

reshape.jpg

結(jié)束

以上就是我對(duì)Blob的一些理解,希望對(duì)大家有幫助毡鉴。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末崔泵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子猪瞬,更是在濱河造成了極大的恐慌憎瘸,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撑螺,死亡現(xiàn)場(chǎng)離奇詭異含思,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)甘晤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)含潘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人线婚,你說(shuō)我怎么就攤上這事遏弱。” “怎么了塞弊?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵漱逸,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我游沿,道長(zhǎng)饰抒,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任诀黍,我火速辦了婚禮袋坑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘眯勾。我一直安慰自己枣宫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布吃环。 她就那樣靜靜地躺著也颤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪郁轻。 梳的紋絲不亂的頭發(fā)上翅娶,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼故觅。 笑死厂庇,一個(gè)胖子當(dāng)著我的面吹牛渠啊,可吹牛的內(nèi)容都是我干的输吏。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼替蛉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼贯溅!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起躲查,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤它浅,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后镣煮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體姐霍,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年典唇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了镊折。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡介衔,死狀恐怖恨胚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情炎咖,我是刑警寧澤赃泡,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站乘盼,受9級(jí)特大地震影響升熊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜绸栅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一级野、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阴幌,春花似錦勺阐、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至议忽,卻和暖如春懒闷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工愤估, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留帮辟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓玩焰,卻偏偏與公主長(zhǎng)得像由驹,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子昔园,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容