異構(gòu)計(jì)算關(guān)鍵技術(shù)之mmap

異構(gòu)計(jì)算關(guān)鍵技術(shù)之mmap

一祸泪、背景

1. 日志存儲(chǔ)系統(tǒng)

case 1:分布式日志存儲(chǔ)系統(tǒng),是一個(gè)基于raft協(xié)議自研分布式日志存儲(chǔ)系統(tǒng),logstore則是底層存儲(chǔ)引擎。

logstore中档悠,使用mmap對(duì)數(shù)據(jù)文件讀寫。

logstore的存儲(chǔ)結(jié)構(gòu)簡(jiǎn)化如下圖:

1707371922276.png

2. 普通bin文件讀取操作

最近博主需要讀取一個(gè)bin文件然爆,然后實(shí)時(shí)和FPGA接收到的數(shù)據(jù)進(jìn)行比對(duì)站粟,驗(yàn)證邏輯的正確性黍图,采用的mmap技術(shù)曾雕。

...
int id = open(Parameter::xxxbin.c_str(), O_RDONLY);
if (fd < 0) {
    std::cout << "cannot open file: " << xxxbin << std::endl;
    return -1;
}

m_binbuff = (char *)mmap(NULL, m_fileSize, PROT_READ, MAP_SHARED, fd, 0);
if(nullptr == m_binBuff){
        std::cout << "Can't mmap file: " << Parameter::xxxbin << std::endl;
        return;
}
close(fd);

3. Ceph分布式文件系統(tǒng)性能關(guān)鍵技術(shù)

分布式文件系統(tǒng)在處理大規(guī)模數(shù)據(jù)時(shí)起著至關(guān)重要的作用。

為了滿足日益增長的數(shù)據(jù)存儲(chǔ)需求助被,Ceph作為一種先進(jìn)的分布式文件系統(tǒng)方案被廣泛使用剖张。

然而,在Ceph的架構(gòu)中揩环,為了實(shí)現(xiàn)高性能和低延遲搔弄,諸如mmap等關(guān)鍵技術(shù)成為了不可或缺的一部分。

二丰滑、什么是mmap

在《深入理解計(jì)算機(jī)系統(tǒng)》書中顾犹,mmap定義為:linux通過將一個(gè)虛擬內(nèi)存區(qū)域與一個(gè)磁盤上的對(duì)象(object)關(guān)聯(lián)起來,以初始化這個(gè)虛擬內(nèi)存的內(nèi)容褒墨,這個(gè)過程稱為內(nèi)存映射(memory mapping)炫刷。

三、mmap的原理

1. mmap在進(jìn)程虛擬內(nèi)存做了什么

我們先來簡(jiǎn)單看一下mapping一個(gè)文件郁妈,mmap做了什么事情浑玛。如下圖所示:

1707372876335.png

假設(shè)我們mmap的文件是FileA,在調(diào)用mmap之后噩咪,會(huì)在進(jìn)程的虛擬內(nèi)存分配地址空間顾彰,創(chuàng)建映射關(guān)系极阅。

這里值得注意的是,mmap只是在虛擬內(nèi)存分配了地址空間涨享,舉個(gè)例子筋搏,假設(shè)上述的FileA(dd創(chuàng)建)是5M大小:

1707376111820.png

在mmap之后厕隧,查看mmap所在進(jìn)程的maps描述拆又,可以看到:

1707376217444.png

由上可以看到,在mmap之后栏账,進(jìn)程的地址空間7f1da0a0f000-7f1da0f0f000被分配帖族,并且map到FileA,7f1da0f0f000減去7f1da0a0f000挡爵,剛好是5242880(ps: 這里是整個(gè)文件做mapping)

2. mmap在物理內(nèi)存做了什么

在Linux中竖般,VM系統(tǒng)通過將虛擬內(nèi)存分割為稱作虛擬頁(Virtual Page,VP)大小固定的塊來處理磁盤(較低層)與上層數(shù)據(jù)的傳輸茶鹃。

一般情況下涣雕,每個(gè)頁的大小默認(rèn)是4096字節(jié)。同樣的闭翩,物理內(nèi)存也被分割為物理頁(Physical Page挣郭,PP),也為4096字節(jié)疗韵。

上述例子兑障,在mmap之后,如下圖:

1707376476961.png

在mmap之后蕉汪,并沒有在將文件內(nèi)容加載到物理頁上流译,只上在虛擬內(nèi)存中分配了地址空間。當(dāng)進(jìn)程在訪問這段地址時(shí)(通過mmap在寫入或讀取時(shí)FileA)者疤,若虛擬內(nèi)存對(duì)應(yīng)的page沒有在物理內(nèi)存中緩存福澡,則產(chǎn)生"缺頁",由內(nèi)核的缺頁異常處理程序處理驹马,將文件對(duì)應(yīng)內(nèi)容革砸,以頁為單位(4096)加載到物理內(nèi)存,注意是只加載缺頁糯累,但也會(huì)受操作系統(tǒng)一些調(diào)度策略影響算利,加載的比所需的多,這里就不展開了寇蚊。

缺頁處理后笔时,如下圖:

1707376514124.png

3. mmap的分類

mmap有兩種類型,一種是有backend仗岸,一種是沒有backend允耿。

有backend

1707376590790.png

這種模式將普通文件做memory mapping(非MAP_ANONYMOUS)借笙,所以在mmap系統(tǒng)調(diào)用時(shí),需要傳入文件的fd较锡。這種模式常見的有兩個(gè)常用的方式业稼,MAP_SHARED與MAP_PRIVATE,但它們的行為卻不相同蚂蕴。

(1) MAP_SHARED

可以從兩個(gè)角度去看:

1. 進(jìn)程間可見:這個(gè)被提及太多低散,就不展開討論了

2. 寫入/更新數(shù)據(jù)會(huì)回寫backend,也就是回寫文件:這個(gè)是很關(guān)鍵的特性骡楼,是在Logstore設(shè)計(jì)實(shí)現(xiàn)時(shí)熔号,需要考慮的重點(diǎn)。

3. Logstore的一個(gè)基本功能就是不斷地寫入數(shù)據(jù)鸟整,從實(shí)現(xiàn)上看就是不斷地mmap文件引镊,往內(nèi)存寫入/更新數(shù)據(jù)以達(dá)到寫入文件的目的。但物理內(nèi)存是有限的篮条,在寫入數(shù)據(jù)超過物理內(nèi)存時(shí)弟头,操作系統(tǒng)會(huì)進(jìn)行頁置換,根據(jù)淘汰算法涉茧,將需要淘汰的頁置換成所需的新頁赴恨,而恰恰因?yàn)槭怯衎ackend的,所以mmap對(duì)應(yīng)的內(nèi)存是可以被淘汰的(若內(nèi)存頁是"臟"的伴栓,則操作系統(tǒng)會(huì)先將數(shù)據(jù)回寫磁盤再淘汰)伦连。

4. 這樣,就算mmap的數(shù)據(jù)遠(yuǎn)大于物理內(nèi)存挣饥,操作系統(tǒng)也能很好地處理除师,不會(huì)產(chǎn)生功能上的問題。

(2) MAP_PRIVATE

這是一個(gè)copy-on-write的映射方式扔枫。雖然他也是有backend的,但在寫入數(shù)據(jù)時(shí)锹安,他會(huì)在物理內(nèi)存copy一份數(shù)據(jù)出來(以頁為單位)短荐,而且這些數(shù)據(jù)是不會(huì)被回寫到文件的。這里就要注意叹哭,因?yàn)楦碌臄?shù)據(jù)是一個(gè)副本忍宋,而且不會(huì)被回寫,這就意味著如果程序運(yùn)行時(shí)不主動(dòng)釋放风罩,若更新的數(shù)據(jù)超過可用物理內(nèi)存+swap space糠排,就會(huì)遇到OOM Killer。

無backend

無backend通常是MAP_ANONYMOUS超升,就是將一個(gè)區(qū)域映射到一個(gè)匿名文件入宦,匿名文件是由內(nèi)核創(chuàng)建的哺徊。

因?yàn)闆]有backend,寫入/更新的數(shù)據(jù)之后乾闰,若不主動(dòng)釋放落追,這些占用的物理內(nèi)存是不能被釋放的,同樣會(huì)出現(xiàn)OOM Killer涯肩。

四轿钠、mmap比內(nèi)存+swap空間大情況下,是否有問題

到這里病苗,這個(gè)問題就比較好解析了疗垛。我們可以將此問題分離為:

  • 虛擬內(nèi)存是否會(huì)出問題
  • 物理內(nèi)存是否會(huì)出問題

虛擬內(nèi)存是否會(huì)出問題

回到上述的"mmap在進(jìn)程虛擬內(nèi)存做了什么",我們知道m(xù)map會(huì)在進(jìn)程的虛擬內(nèi)存中分配地址空間硫朦,比如1G的文件继谚,則分配1G的連續(xù)地址空間。那究竟可以maping多少呢阵幸?在64位操作系統(tǒng)花履,尋址范圍是2^64 ,除去一些內(nèi)核挚赊、進(jìn)程數(shù)據(jù)等地址段之外诡壁,基本上可以認(rèn)為可以mapping無限大的數(shù)據(jù)(不太嚴(yán)謹(jǐn)?shù)恼f法)。

物理內(nèi)存是否會(huì)出問題

回到上述"mmap的分類"荠割,對(duì)于有backend的mmap妹卿,而且是能回寫到文件的,映射比內(nèi)存+swap空間大是沒有問題的蔑鹦。但無法回寫到文件的夺克,需要非常注意,主動(dòng)釋放嚎朽。

五铺纽、mmap的性能

mmap的性能經(jīng)常與系統(tǒng)調(diào)用(write/read)做對(duì)比。

我們將讀寫分開看哟忍,先嘗試從原理上分析兩者的差異狡门,然后再通過測(cè)試驗(yàn)證。

1. mmap的寫性能

我們先來簡(jiǎn)單講講write系統(tǒng)調(diào)用寫文件的過程:

v2-cd75cdde9843536276ded020e6790124_r.jpg
Step1:進(jìn)程(用戶態(tài))調(diào)用write系統(tǒng)調(diào)用锅很,并告訴內(nèi)核需要寫入數(shù)據(jù)的開始地址與長度(告訴內(nèi)核寫入的數(shù)據(jù)在哪)其馏。

Step2:內(nèi)核write方法,將校驗(yàn)用戶態(tài)的數(shù)據(jù)爆安,然后復(fù)制到kernel buffer(這里是Page Cache)叛复。

Step3: 由操作系統(tǒng)調(diào)用,將臟頁回寫到磁盤(通常這是異步的)

再來簡(jiǎn)單講講使用mmap時(shí),寫入文件流程:

Step1:進(jìn)程(用戶態(tài))將需要寫入的數(shù)據(jù)直接copy到對(duì)應(yīng)的mmap地址(內(nèi)存copy)

Step2:
    (2.1) 若mmap地址未對(duì)應(yīng)物理內(nèi)存褐奥,則產(chǎn)生缺頁異常咖耘,由內(nèi)核處理
    (2.2) 若已對(duì)應(yīng),則直接copy到對(duì)應(yīng)的物理內(nèi)存

Step3:由操作系統(tǒng)調(diào)用抖僵,將臟頁回寫到磁盤(通常這是異步的)

系統(tǒng)調(diào)用會(huì)對(duì)性能有影響鲤看,那么從理論上分析:

1. 若每次寫入的數(shù)據(jù)大小接近page size(4096),那么write調(diào)用與mmap的寫性能應(yīng)該比較接近(因?yàn)橄到y(tǒng)調(diào)用次數(shù)相近)

2. 若每次寫入的數(shù)據(jù)非常小耍群,那么write調(diào)用的性能應(yīng)該遠(yuǎn)慢于mmap的性能义桂。

下面我們對(duì)兩者進(jìn)行性能測(cè)試:

每次寫入大小 | mmap 耗時(shí) | write 耗時(shí)
--------------- | ------- | -------- | --------
| 1 byte | 22.14s | >300s
| 100 bytes | 2.84s | 22.86s
| 512 bytes | 2.51s | 5.43s
| 1024 bytes | 2.48s | 3.48s
| 2048 bytes | 2.47s | 2.34s
| 4096 bytes | 2.48s | 1.74s
| 8192 bytes | 2.45s | 1.67s
| 10240 bytes | 2.49s | 1.65s

可以看到mmap在100byte寫入時(shí)已經(jīng)基本達(dá)到最大寫入性能,而write調(diào)用需要在4096(也就是一個(gè)page size)時(shí)蹈垢,才能達(dá)到最大寫入性能慷吊。

從測(cè)試結(jié)果可以看出,在寫小數(shù)據(jù)時(shí)曹抬,mmap會(huì)比write調(diào)用快溉瓶,但在寫大數(shù)據(jù)時(shí),反而沒那么快谤民。

2. mmap的讀性能

我們還是來簡(jiǎn)單分析read調(diào)用與mmap的流程:

v2-c188b57f312663c6e7e87ca0fbe9d0b8_r.jpg

從圖中可以看出堰酿,read調(diào)用確實(shí)比mmap多一次copy。因?yàn)閞ead調(diào)用张足,進(jìn)程是無法直接訪問kernel space的触创,所以在read系統(tǒng)調(diào)用返回前,內(nèi)核需要將數(shù)據(jù)從內(nèi)核復(fù)制到進(jìn)程指定的buffer为牍。但mmap之后哼绑,進(jìn)程可以直接訪問mmap的數(shù)據(jù)(page cache)。
從原理上看碉咆,read性能會(huì)比mmap慢抖韩。

每次讀取大小 | mmap 耗時(shí) | write 耗時(shí)
--------------- | ------- | -------- | --------
| 1 byte | 8215.4ms | > 300s
| 100 bytes | 86.4ms | 8100.9ms
| 512 bytes | 16.14ms | 1851.45ms
| 1024 bytes | 8.11ms | 992.71ms
| 2048 bytes | 4.09ms | 636.85ms
| 4096 bytes | 2.07ms | 558.10ms
| 8192 bytes | 1.06ms | 444.83ms
| 10240 bytes | 867.88μs | 475.28ms

由上可以看出,在read上面疫铜,mmap比write的性能差別還是很大的茂浮。測(cè)試結(jié)果與理論推導(dǎo)吻合。

3. 總結(jié)

mmap被廣泛應(yīng)用于提高讀取性能块攒。傳統(tǒng)上励稳,讀取數(shù)據(jù)需要通過復(fù)制數(shù)據(jù)到用戶空間,這一過程涉及系統(tǒng)調(diào)用和數(shù)據(jù)拷貝操作囱井,消耗大量的CPU資源和時(shí)間。而通過使用mmap趣避,用戶可以直接在內(nèi)存中讀取文件庞呕,避免了這些開銷。因此,在Ceph中使用mmap可以提高文件讀取的效率住练。

然而地啰,并不是所有場(chǎng)景下mmap都適用。比如讲逛,對(duì)于大型文件或者需要修改文件內(nèi)容的場(chǎng)景亏吝,mmap可能并不是最佳選擇。因?yàn)橐坏┦褂胢map映射了文件盏混,文件的全部?jī)?nèi)容都會(huì)加載到內(nèi)存中蔚鸥,這會(huì)導(dǎo)致內(nèi)存消耗過大。并且许赃,修改文件內(nèi)容會(huì)引起復(fù)制寫操作止喷,降低寫入性能。因此混聊,在使用mmap時(shí)弹谁,需要根據(jù)實(shí)際情況進(jìn)行權(quán)衡和選擇。

六句喜、未完待續(xù)

下章將繼續(xù)介紹異構(gòu)計(jì)算的關(guān)鍵技術(shù):多線程的深度探索與應(yīng)用预愤。

歡迎關(guān)注知乎:北京不北,+vbeijing_bubei

歡迎+V:beijing_bubei

歡迎關(guān)注douyin:near.X (北京不北)

獲得免費(fèi)答疑咳胃,長期技術(shù)交流植康。

七、參考文獻(xiàn)

https://zhuanlan.zhihu.com/p/553423923

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拙绊,一起剝皮案震驚了整個(gè)濱河市向图,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌标沪,老刑警劉巖榄攀,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異金句,居然都是意外死亡檩赢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門违寞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贞瞒,“玉大人,你說我怎么就攤上這事趁曼【” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵挡闰,是天一觀的道長乒融。 經(jīng)常有香客問我掰盘,道長,這世上最難降的妖魔是什么赞季? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任愧捕,我火速辦了婚禮,結(jié)果婚禮上申钩,老公的妹妹穿的比我還像新娘次绘。我一直安慰自己,他們只是感情好撒遣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布邮偎。 她就那樣靜靜地躺著,像睡著了一般愉舔。 火紅的嫁衣襯著肌膚如雪钢猛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天轩缤,我揣著相機(jī)與錄音命迈,去河邊找鬼。 笑死火的,一個(gè)胖子當(dāng)著我的面吹牛壶愤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播馏鹤,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼征椒,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了湃累?” 一聲冷哼從身側(cè)響起勃救,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎治力,沒想到半個(gè)月后蒙秒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宵统,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年晕讲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片马澈。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瓢省,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出痊班,到底是詐尸還是另有隱情勤婚,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布涤伐,位于F島的核電站蛔六,受9級(jí)特大地震影響荆永,放射性物質(zhì)發(fā)生泄漏废亭。R本人自食惡果不足惜国章,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望豆村。 院中可真熱鬧液兽,春花似錦、人聲如沸掌动。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽粗恢。三九已至柑晒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間眷射,已是汗流浹背匙赞。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妖碉,地道東北人涌庭。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像欧宜,于是被迫代替她去往敵國和親坐榆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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