mmap原理簡析

mmap Memory Mapping


image.png

原理

首先玖喘,“映射”這個(gè)詞茵休,就和數(shù)學(xué)課上說的“一一映射”是一個(gè)意思赛惩,就是建立一種一一對(duì)應(yīng)關(guān)系,在這里主要是只 硬盤上文件 的位置與進(jìn)程 邏輯地址空間 中一塊大小相同的區(qū)域之間的一一對(duì)應(yīng)搞旭,如圖1中過程1所示散怖。這種對(duì)應(yīng)關(guān)系純屬是邏輯上的概念,物理上是不存在的肄渗,原因是進(jìn)程的邏輯地址空間本身就是不存在的镇眷。在內(nèi)存映射的過程中,并沒有實(shí)際的數(shù)據(jù)拷貝翎嫡,文件沒有被載入內(nèi)存欠动,只是邏輯上被放入了內(nèi)存,具體到代碼惑申,就是建立并初始化了相關(guān)的數(shù)據(jù)結(jié)構(gòu)(struct address_space)具伍,這個(gè)過程有系統(tǒng)調(diào)用mmap()實(shí)現(xiàn),所以建立內(nèi)存映射的效率很高硝桩。

內(nèi)存映射過程.png

既然建立內(nèi)存映射沒有進(jìn)行實(shí)際的數(shù)據(jù)拷貝沿猜,那么進(jìn)程又怎么能最終直接通過內(nèi)存操作訪問到硬盤上的文件呢枚荣?那就要看內(nèi)存映射之后的幾個(gè)相關(guān)的過程了碗脊。

mmap()會(huì)返回一個(gè)指針ptr,它指向進(jìn)程邏輯地址空間中的一個(gè)地址橄妆,這樣以后衙伶,進(jìn)程無需再調(diào)用read或write對(duì)文件進(jìn)行讀寫,而只需要通過ptr就能夠操作文件害碾。但是ptr所指向的是一個(gè)邏輯地址矢劲,要操作其中的數(shù)據(jù),必須通過MMU將邏輯地址轉(zhuǎn)換成物理地址慌随,如圖1中過程2所示芬沉。這個(gè)過程與內(nèi)存映射無關(guān)。

前面講過阁猜,建立內(nèi)存映射并沒有實(shí)際拷貝數(shù)據(jù)丸逸,這時(shí),MMU在地址映射表中是無法找到與ptr相對(duì)應(yīng)的物理地址的剃袍,也就是MMU失敗黄刚,將產(chǎn)生一個(gè)缺頁中斷,缺頁中斷的中斷響應(yīng)函數(shù)會(huì)在swap中尋找相對(duì)應(yīng)的頁面民效,如果找不到(也就是該文件從來沒有被讀入內(nèi)存的情況)憔维,則會(huì)通過mmap()建立的映射關(guān)系涛救,從硬盤上將文件讀取到物理內(nèi)存中,如圖1中過程3所示业扒。這個(gè)過程與內(nèi)存映射無關(guān)检吆。

如果在拷貝數(shù)據(jù)時(shí),發(fā)現(xiàn)物理內(nèi)存不夠用程储,則會(huì)通過虛擬內(nèi)存機(jī)制(swap)將暫時(shí)不用的物理頁面交換到硬盤上咧栗,如圖1中過程4所示。這個(gè)過程也與內(nèi)存映射無關(guān)虱肄。

效率

從代碼層面上看致板,從硬盤上將文件讀入內(nèi)存,都要經(jīng)過文件系統(tǒng)進(jìn)行數(shù)據(jù)拷貝咏窿,并且數(shù)據(jù)拷貝操作是由文件系統(tǒng)和硬件驅(qū)動(dòng)實(shí)現(xiàn)的斟或,理論上來說,拷貝數(shù)據(jù)的效率是一樣的集嵌。但是通過內(nèi)存映射的方法訪問硬盤上的文件萝挤,效率要比read和write系統(tǒng)調(diào)用高,這是為什么呢根欧?原因是read()是系統(tǒng)調(diào)用怜珍,其中進(jìn)行了數(shù)據(jù)拷貝,它首先將文件內(nèi)容從硬盤拷貝到內(nèi)核空間的一個(gè)緩沖區(qū)凤粗,如圖2中過程1酥泛,然后再將這些數(shù)據(jù)拷貝到用戶空間,如圖2中過程2嫌拣,在這個(gè)過程中柔袁,實(shí)際上完成了 兩次數(shù)據(jù)拷貝 ;而mmap()也是系統(tǒng)調(diào)用异逐,如前所述捶索,mmap()中沒有進(jìn)行數(shù)據(jù)拷貝,真正的數(shù)據(jù)拷貝是在缺頁中斷處理時(shí)進(jìn)行的灰瞻,由于mmap()將文件直接映射到用戶空間腥例,所以中斷處理函數(shù)根據(jù)這個(gè)映射關(guān)系,直接將文件從硬盤拷貝到用戶空間酝润,只進(jìn)行了 一次數(shù)據(jù)拷貝 燎竖。因此,內(nèi)存映射的效率要比read/write效率高袍祖。

read系統(tǒng)調(diào)用過程.png

下面這個(gè)程序底瓣,通過read和mmap兩種方法分別對(duì)硬盤上一個(gè)名為“mmap_test”的文件進(jìn)行操作,文件中存有10000個(gè)整數(shù),程序兩次使用不同的方法將它們讀出捐凭,加1拨扶,再寫回硬盤。通過對(duì)比可以看出茁肠,read消耗的時(shí)間將近是mmap的兩到三倍患民。

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/time.h>
#include<fcntl.h>
#include<sys/mman.h>
 
#define MAX 10000
 
int main()
{
int i=0;
int count=0, fd=0;
struct timeval tv1, tv2;
int *array = (int *)malloc( sizeof(int)*MAX );
 
/*read*/
 
gettimeofday( &tv1, NULL );
fd = open( "mmap_test", O_RDWR );
if( sizeof(int)*MAX != read( fd, (void *)array, sizeof(int)*MAX ) )
{
printf( "Reading data failed.../n" );
return -1;
}
for( i=0; i<MAX; ++i )
 
++array[ i ];
if( sizeof(int)*MAX != write( fd, (void *)array, sizeof(int)*MAX ) )
{
printf( "Writing data failed.../n" );
return -1;
}
free( array );
close( fd );
gettimeofday( &tv2, NULL );
printf( "Time of read/write: %dms/n", tv2.tv_usec-tv1.tv_usec );
 
/*mmap*/
 
gettimeofday( &tv1, NULL );
fd = open( "mmap_test", O_RDWR );
array = mmap( NULL, sizeof(int)*MAX, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0 );
for( i=0; i<MAX; ++i )
 
++array[ i ];
munmap( array, sizeof(int)*MAX );
msync( array, sizeof(int)*MAX, MS_SYNC );
free( array );
close( fd );
gettimeofday( &tv2, NULL );
printf( "Time of mmap: %dms/n", tv2.tv_usec-tv1.tv_usec );
 
return 0;
}

輸出結(jié)果:

Time of read/write: 154ms

Time of mmap: 68ms

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市垦梆,隨后出現(xiàn)的幾起案子匹颤,更是在濱河造成了極大的恐慌,老刑警劉巖托猩,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件印蓖,死亡現(xiàn)場離奇詭異,居然都是意外死亡京腥,警方通過查閱死者的電腦和手機(jī)赦肃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來公浪,“玉大人他宛,你說我怎么就攤上這事∏菲” “怎么了厅各?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長预柒。 經(jīng)常有香客問我队塘,道長,這世上最難降的妖魔是什么卫旱? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任人灼,我火速辦了婚禮,結(jié)果婚禮上顾翼,老公的妹妹穿的比我還像新娘。我一直安慰自己奈泪,他們只是感情好适贸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著涝桅,像睡著了一般拜姿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上冯遂,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天蕊肥,我揣著相機(jī)與錄音,去河邊找鬼。 笑死壁却,一個(gè)胖子當(dāng)著我的面吹牛批狱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播展东,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赔硫,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了盐肃?” 一聲冷哼從身側(cè)響起爪膊,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎砸王,沒想到半個(gè)月后推盛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谦铃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年小槐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荷辕。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凿跳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出疮方,到底是詐尸還是另有隱情控嗜,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布骡显,位于F島的核電站疆栏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏惫谤。R本人自食惡果不足惜壁顶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望溜歪。 院中可真熱鬧若专,春花似錦、人聲如沸蝴猪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽自阱。三九已至嚎莉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沛豌,已是汗流浹背趋箩。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人叫确。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓跳芳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親启妹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子筛严,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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

  • mmap基礎(chǔ)概念 mmap是一種內(nèi)存映射文件的方法,即將一個(gè)文件或者其它對(duì)象映射到進(jìn)程的地址空間饶米,實(shí)現(xiàn)文件磁盤地址...
    dequal閱讀 1,204評(píng)論 0 1
  • 轉(zhuǎn)自認(rèn)真分析mmap:是什么 為什么 怎么用 閱讀目錄mmap基礎(chǔ)概念mmap內(nèi)存映射原理mmap和常規(guī)文件操作的...
    扎Zn了老Fe閱讀 840評(píng)論 0 3
  • Linux進(jìn)程通信實(shí)現(xiàn)機(jī)制有很多桨啃,也有各自優(yōu)缺點(diǎn)和適用場景,關(guān)于她們之間的對(duì)比檬输,等各種通信機(jī)制一一介紹后照瘾,再來一個(gè)...
    batbattle閱讀 4,075評(píng)論 3 13
  • mmap基礎(chǔ)概念 mmap是一種內(nèi)存映射文件的方法,即將一個(gè)文件或者其它對(duì)象映射到進(jìn)程的地址空間丧慈,實(shí)現(xiàn)文件磁盤地址...
    神奇的考拉閱讀 2,198評(píng)論 3 6
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,938評(píng)論 2 89