對linux的IO的再認識
呃,其實我對linux的IO感興趣主要的動力是為了讓zlog寫日志文件更快一點。雖然zlog是個用戶態的函數庫,但為了提升速度,必須對linux底層的機制有一定的了解。
OK,言歸正傳,從我的各個階段認識層次開始說起吧。
1.一開始,我對linux的IO層的認識從標準IO庫開始,從《C程序設計語言》(TCPL)中知道有
2.讀了《UNIX高級編程》(APUE)后,知道了stdio.h實現了讀寫緩存,目的是為了減少系統調用的開銷,最后真正工作的系統調用是read和write。
3.精讀《UNIX高級編程》后,知道read和write也不是直接寫設備,而是把數據從用戶態內存拷貝到內核緩沖區(也就是page cache),或者反過來,這是二次緩沖。內核需要把多個進程的讀寫合并,并且放到寫隊列中。從這里開始,理解了stdio.h和read/write都是同步IO。還有異步IO,但是目前在linux下沒有成熟的異步IO庫。關于異步IO有一篇文章《Linux kernel AIO這個奇葩》。
4.《UNIX高級編程》中提及了mmap,另一種IO機制,由文件映射來實現IO。在stevens的另一本書中說得更加詳細點,《UNIX網絡編程,卷2》。
5.以上都是對系統接口的使用,在去年我粗讀了《深入理解計算機系統》(CSAPP),對linux的虛擬內存機制有一定的了解。有一篇總結文章寫得很好,我就不重復了,是《系統調用分析》。當然最直接的方法是去啃內核,不過我對內核還是包有一定的恐懼心理,暫時擱置。
6.不過在網絡上的搜索過程中,我看到了02年的linus關于O_DIRECT的討論,終于知道了linuxIO的系統為什么是這么設計的,為什么到目前為止異步IO還是沒有成熟,以及一系列問題的答案,接下來我要開始吐槽和摘要這篇文章。
-------------------------------------------------------------------------------------------------------------------------
緣起:有人說read和write的O_DIRECT選項速度極快,于是激怒了linus
linus反擊:
O_DIRECT這個接口就是傻逼,可能是一幫磕了藥的神經錯亂的猴子設計出來的。[*]
[*] 換種說法,這是***
(Oracle)
這組接口的優點在于,從page cache層到用戶態內存之間,并非復制,而是移動。通過對用戶進程空間的內存映射和修改頁表,達到了0復制的效果。實際上,目前linux基本實現了readahead和mmap,而設想中的mwrite和fdatasync_area未實現。
那么,為什么linus一直拒絕O_DIRECT這種繞開page cache的“高效”的方式來實現同步IO呢?他后面提了page cache設計的三個原因:
linus認為,簡單的繞過page cache是平庸的,人們太關注“繞過緩存直達硬盤”這種概念了。進一步深入的比較read/write和mmap的性能差距,linus談到:
Yes. However, it's even _nicer_ if you don't need to walk the page tables at all. Quite a lot of operations could be done directly on the page cache. I'm not a huge fan of mmap() myself - the biggest advantage of mmap is when you don't know your access patterns, and you have reasonably good locality. In many other cases mmap is just a total loss, because the page table walking is often more expensive than even a memcpy(). That's _especially_ true if you have to move mappings around, and you have to invalidate TLB's. memcpy() often gets a bad name. Yeah, memory is slow, but especially if you copy something you just worked on, you're actually often better off letting the CPU cache do its job, rather than walking page tables and trying to be clever. Just as an example: copying often means that you don't need nearly as much locking and synchronization - which in turn avoids one whole big mess (yes, the memcpy() will look very hot in profiles, but then doing extra work to avoid the memcpy() will cause spread-out overhead that is a lot worse and harder to think about). This is why a simple read()/write() loop often _beats_ mmap approaches. And often it's actually better to not even have big buffers (ie the old "avoid system calls by aggregation" approach) because that just blows your cache away. Right now, the fastest way to copy a file is apparently by doing lots of ~8kB read/write pairs (that data may be slightly stale, but it was true at some point). Never mind the system call overhead - just having the extra buffer stay in the L1 cache and avoiding page faults from mmap is a bigger win. And I don't think mmap _can_ beat that. It's fundamental. In contrast, direct page cache accesses really can do so. Exactly because they don't touch any page tables at all, and because they can take advantage of internal kernel data structure layout and move pages around without any cost..
也就是說,memcpy雖然名聲很差,因為內存很慢,但其實大部分memcpy的工作由CPU的L1 cache完成了。相比之下,mmap的工作需要遍歷頁表,而一次page fault就會進入中斷。所以 8KB每次的read/write的速度往往比mmap要快,只要這8KB都在L1 cache中。但如果實現了linus所說的智能的mwrite,就可以避免頁表的使用,而只是由page cache來完成工作。
在郵件列表中,linus頻繁抨擊Oracle和寫數據庫的那伙人,正是因為他們對O_DIRECT的濫用破壞了接口的完整性。
在這個帖子里面我發現了inux的系統調用splice/vmsplice,可以最快的從兩個文件描述符之間拷貝數據,詳見《splice系列系統調用》關于page cache,我另外找到一篇文章,講得很好《Linux Cache 機制探究》。
這個帖子里面還有其他好玩的點:
a.linus相信大規模的微機會打敗小規模的大機,并且他認為這就是為什么windows和linux這二十年成功的原因。小就是美。目前看來,智能手機也是這個進程的一部分。
b.linus預言隨著內存的增長,內存數據庫會干掉現在的一堆垃圾(當時的數據庫)。內存數據庫將解決目前的IO問題,唯一需要對硬盤做的操作的就是寫日志和讀備份。現在距離他作出預言已經過了10年,看來事情正像他所說得那樣發展。
c.linus說大家不要把我看的太認真,我知道自己相信什么,但linux的某種美妙之處在于linus所相信的并不重要
d.郵件列表中有Larry McVoy,后來發現他是一個挺有名的內核維護者,同時他還搞了商業版本控制軟件BitKeeper,并且被linus用于linux內核的版本管理。但后來兩者分道揚鑣,詳見《BitKeeper姻緣了斷》。而linus開發了自己的版本控制系統git。
-------------------------------------------------------------------------------------------------------------------------
7. 我做了一些實驗,關于fwrite/write/mmap的性能對比,結論還是挺有趣的,目前還沒整理好,且聽下回分解~~
Linux 數據庫
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。