linux下零拷貝技術(shù)介紹

傳統(tǒng)的數(shù)據(jù)傳輸方式
很長(zhǎng)一段時(shí)間內(nèi),數(shù)據(jù)拷貝的認(rèn)識(shí)僅僅停留在應(yīng)用程序?qū)?,?shí)際上隱藏在背后的數(shù)據(jù)拷貝行為比想象的要多的多。在傳輸數(shù)據(jù)的時(shí)候,用戶應(yīng)用程序需要分配一塊合適大小的緩沖區(qū)來存放需要傳輸?shù)臄?shù)據(jù)。用戶從應(yīng)用程序中讀取數(shù)據(jù),然后發(fā)送出去,只需要兩個(gè)系統(tǒng)調(diào)用read,write即可完成數(shù)據(jù)傳輸工作,應(yīng)用程序并不知道這個(gè)數(shù)據(jù)傳輸過程中操作系統(tǒng)進(jìn)行了多少次拷貝操作。某些情況下,這些數(shù)據(jù)拷貝操作會(huì)極大的降低數(shù)據(jù)傳輸?shù)男阅堋?NIC,Network Interface Card )
傳統(tǒng)的數(shù)據(jù)拷貝方式,如下圖:
上線文切換,如圖:
涉及的步驟:
(1)read()調(diào)用引發(fā)從用戶模式到內(nèi)核模式的上下文切換(第一次切換),在內(nèi)部,發(fā)出sys_read(或者同等內(nèi)容)從設(shè)備中讀取數(shù)據(jù),直接內(nèi)存讀取(direct memory access,DMA)執(zhí)行了拷貝(第一次拷貝),它從磁盤中讀取內(nèi)容,然后將他們存儲(chǔ)到一個(gè)內(nèi)核地址空間緩沖區(qū)中;
(2)數(shù)據(jù)從讀緩沖區(qū)拷貝到用戶緩沖區(qū)(第二次拷貝),read()調(diào)用返回。該調(diào)用返回引發(fā)內(nèi)核模式到用戶模式的切換(第二次切換)?,F(xiàn)在數(shù)據(jù)被存儲(chǔ)在用戶空間緩沖區(qū)中;
(3) send()套接字調(diào)用引發(fā)用戶模式到內(nèi)核模式的上下文切換(第三次切換),數(shù)據(jù)再次被放置到內(nèi)核地址空間緩沖區(qū)中(第三次拷貝)。這次放置的緩沖區(qū)與目標(biāo)套接字關(guān)聯(lián);
(4) send()系統(tǒng)調(diào)用返回,從內(nèi)核模式切換到用戶模式(第四次切換),DMA引擎將數(shù)據(jù)從內(nèi)核緩沖區(qū)傳輸?shù)絽f(xié)議引擎(第四次拷貝)。
DMA允許外圍設(shè)備和貯存之間直接傳輸IO數(shù)據(jù),DMA依賴于系統(tǒng)。每一種體系結(jié)構(gòu)DMA傳輸不同,編程接口也不同。數(shù)據(jù)傳輸可以以兩種方式觸發(fā):一種所軟件請(qǐng)求數(shù)據(jù),另一種所硬件異步傳輸。以read為例,它即采用第一種方式,其步驟如下:
(1) 進(jìn)程調(diào)用read時(shí),驅(qū)動(dòng)程序分配一個(gè)DMA緩沖區(qū),隨后指示硬件傳送它的數(shù)據(jù),進(jìn)程進(jìn)入睡眠;
(2) 硬件將數(shù)據(jù)寫入DMA緩沖區(qū)并在完成時(shí)產(chǎn)生一個(gè)中斷;
(3) 中斷處理程序獲取輸入數(shù)據(jù),應(yīng)答中斷,最后喚醒進(jìn)程,可以讀取數(shù)據(jù)了。
由此可見,在傳統(tǒng)的數(shù)據(jù)傳輸中,系統(tǒng)方面總共進(jìn)行了4次數(shù)據(jù)拷貝,4次上線文切換,這些都會(huì)對(duì)服務(wù)器性能造成很大影響。
零拷貝概述
簡(jiǎn)單的說,零拷貝是一種避免CPU將數(shù)據(jù)從一快存儲(chǔ)拷貝到另外一塊存儲(chǔ)的技術(shù)。零拷貝技術(shù)的目標(biāo):
避免數(shù)據(jù)拷貝
#避免操作系統(tǒng)內(nèi)核緩沖區(qū)之間進(jìn)行數(shù)據(jù)拷貝操作;
#避免操作系統(tǒng)內(nèi)核和用戶應(yīng)用程序地址空間之間進(jìn)行數(shù)據(jù)拷貝操作;
#用戶應(yīng)用程序可以避免操作系統(tǒng)直接訪問硬件存儲(chǔ);
#數(shù)據(jù)傳輸盡量讓DMA來處理。
多種操作結(jié)合在一起
#避免不必要的系統(tǒng)調(diào)用和上下文切換;
#需要拷貝的數(shù)據(jù)可以先緩存起來;
#對(duì)數(shù)據(jù)進(jìn)行的處理盡量讓硬件來做。
零拷貝的實(shí)現(xiàn)方式分類
直接IO
主要是通過減少操作系統(tǒng)內(nèi)核緩沖區(qū)和應(yīng)用程序地址空間數(shù)據(jù)拷貝次數(shù),降低對(duì)文件讀取和寫入時(shí)帶來的CPU使用和帶寬的開銷。對(duì)于某些頁數(shù)的應(yīng)用程序,比如說自緩沖應(yīng)用程序來說,會(huì)是一個(gè)比較好的選擇。如果要傳輸?shù)臄?shù)據(jù)量大,使用直接IO的方式進(jìn)行數(shù)據(jù)傳輸,而不需要操作系統(tǒng)內(nèi)核地址空間拷貝數(shù)據(jù)的參與,這將會(huì)提高性能。
直接IO并不是所有的情況下都有效。設(shè)置直接IO的開銷非常大,而且不能利用緩存IO的優(yōu)勢(shì)。直接IO的讀操作會(huì)造成磁盤的同步讀,執(zhí)行進(jìn)程需要在很長(zhǎng)的時(shí)間才能執(zhí)行完;而寫操作會(huì)導(dǎo)致應(yīng)用程序關(guān)閉緩慢。應(yīng)用程序使用直接IO進(jìn)行數(shù)據(jù)傳輸通常和異步IO結(jié)合使用。
linux內(nèi)核已經(jīng)為快設(shè)備執(zhí)行直接IO提供了支持,應(yīng)用程序直接訪問文件而不經(jīng)過操作系統(tǒng)頁高速緩沖存儲(chǔ)器的時(shí)候,打開文件(open() syscall)指定O_DIRECT標(biāo)示符。
總之,這種數(shù)據(jù)傳輸方式,應(yīng)用程序直接訪問硬件存儲(chǔ),操作系統(tǒng)內(nèi)核只是輔助數(shù)據(jù)傳輸;它一般用于操作系統(tǒng)不需要對(duì)數(shù)據(jù)進(jìn)行處理的情況,數(shù)據(jù)可以再應(yīng)用程序地址空間的緩沖區(qū)和磁盤之間進(jìn)行傳輸,而不需要linux操作系統(tǒng)內(nèi)核提供頁緩存支持。
針對(duì)數(shù)據(jù)傳輸不需要經(jīng)過應(yīng)用程序地址空間的零拷貝技術(shù)
數(shù)據(jù)傳輸過程中,避免數(shù)據(jù)在系統(tǒng)內(nèi)核地址空間的緩沖區(qū)和用戶應(yīng)用程序地址空間的緩沖區(qū)進(jìn)行拷貝。有時(shí)候,應(yīng)用程序在數(shù)據(jù)傳輸?shù)倪^程中不需要對(duì)數(shù)據(jù)進(jìn)行訪問,將數(shù)據(jù)從linux的頁緩存拷貝到用戶進(jìn)程的緩沖區(qū)就可以完全避免,傳輸?shù)臄?shù)據(jù)在頁緩沖中就可以處理。在某些情況下,這種零拷貝技術(shù)能獲得很好的性能。linux下提供類似的系統(tǒng)調(diào)用主要有mmap(),sendfile(),splice().
使用mmap替代read,可以減少CPU拷貝次數(shù)。當(dāng)應(yīng)用程序調(diào)用mmap()之后,數(shù)據(jù)通過DMA拷貝拷貝到內(nèi)核緩沖區(qū),應(yīng)用程序和操作系統(tǒng)共享這個(gè)緩沖區(qū)。這樣,操作系統(tǒng)內(nèi)核和應(yīng)用程序存儲(chǔ)空間不再需要進(jìn)行任何的數(shù)據(jù)拷貝操作。當(dāng)進(jìn)行write()系統(tǒng)調(diào)用時(shí),數(shù)據(jù)由內(nèi)核緩沖區(qū)拷貝到socket緩沖區(qū),再拷貝到協(xié)議引擎中。
這種也比較適用于傳送的數(shù)據(jù)不需要經(jīng)過操作系統(tǒng)內(nèi)核的處理或者不需要經(jīng)過程序的處理直接傳輸?shù)那闆r。結(jié)合socket也能使用mmap,不過只能在RAW的情況下使用。對(duì)于傳統(tǒng)的C/S網(wǎng)絡(luò)游戲結(jié)構(gòu)來說,使用的意義不大。
對(duì)應(yīng)用程序地址空間和內(nèi)核空間的數(shù)據(jù)傳輸進(jìn)行優(yōu)化的零拷貝技術(shù)
對(duì)數(shù)據(jù)在linux頁緩存和用戶進(jìn)程緩沖區(qū)之間的傳輸進(jìn)行優(yōu)化。該零拷貝技術(shù)側(cè)重于靈活的處理數(shù)據(jù)在用戶進(jìn)程中的緩沖區(qū)和操作系統(tǒng)的頁緩沖區(qū)之間的拷貝操作。這種方式延續(xù)了傳統(tǒng)的通信方式,但是更加靈活。linux中該方法主要利用寫時(shí)復(fù)制技術(shù)。
寫時(shí)復(fù)制是計(jì)算機(jī)編程中常見的一種優(yōu)化策略,基本思想是這樣的:如果多個(gè)應(yīng)用程序需要同時(shí)訪問一塊數(shù)據(jù),那么可以為這些應(yīng)用程序分配指向這塊數(shù)據(jù)的指針,在每個(gè)應(yīng)用程序看來,他們都擁有這塊數(shù)據(jù)的一份拷貝,當(dāng)其中一個(gè)應(yīng)用程序需要對(duì)自己的這份數(shù)據(jù)進(jìn)行修改時(shí),就需要將數(shù)據(jù)真正的拷貝到應(yīng)用程序的地址空間去。如果應(yīng)用程序永遠(yuǎn)不會(huì)對(duì)這塊數(shù)據(jù)進(jìn)行修改,那么就永遠(yuǎn)不需要將數(shù)據(jù)拷貝到應(yīng)用程序的地址空間去。在stl中string的實(shí)現(xiàn)類似這種策略。
參考:
linux 中的零拷貝技術(shù) 第1部分
http://www.ibm.com/developerworks/cn/linux/l-cn-zerocopy1/index.html
linux 中的零拷貝技術(shù) 第2部分
http://www.ibm.com/developerworks/cn/linux/l-cn-zerocopy2/index.html
linux系統(tǒng)內(nèi)核空間與用戶空間通信的實(shí)現(xiàn)與分析
http://www.ibm.com/developerworks/cn/linux/l-netlink/
從linux內(nèi)核訪問用戶空間內(nèi)存
http://www.ibm.com/developerworks/cn/linux/l-kernel-memory-access/
linux中直接IO機(jī)制的介紹
http://www.ibm.com/developerworks/cn/linux/l-cn-directio/
通過零拷貝實(shí)現(xiàn)有效的數(shù)據(jù)傳輸
http://www.ibm.com/developerworks/cn/java/j-zerocopy/
相關(guān)文章
Fedora Linux 42 穩(wěn)定版發(fā)布: 帶來大量新功能和軟件更新
Fedora 42昨日發(fā)布,這是 Red Hat 贊助開發(fā)的杰出前沿 Linux 發(fā)行版的最新版,包含大量新功能和軟件更新,使其成為 2025 年上半年發(fā)布的一款出色的 Linux 操作系統(tǒng)之一,內(nèi)2025-04-16如何在Linux查看硬盤信息? 查看Linux硬盤大小類型和硬件信息的5種方法
使用Linux系統(tǒng)的過程中,查看和了解硬盤信息是非常重要的工作,尤其是對(duì)于系統(tǒng)管理員而言,那么在Linux系統(tǒng)中如何查看硬盤信息?以下是具體內(nèi)容介紹2025-03-12如何在 Linux 中查看 CPU 詳細(xì)信息? 3招輕松查看CPU型號(hào)、核心數(shù)和溫度
在日常運(yùn)維工作中,獲取 CPU 信息是系統(tǒng)運(yùn)維管理員常見的工作內(nèi)容,無論是為了性能調(diào)優(yōu)、硬件升級(jí)還是僅僅滿足好奇心2025-03-11什么是 Arch Linux? 獨(dú)樹一幟的Arch Linux發(fā)行版分析
Arch Linux是為簡(jiǎn)化,優(yōu)化,現(xiàn)代化,實(shí)用主義,用戶中心和多功能性而創(chuàng)建Linux發(fā)行版,究竟是什么讓 Arch 與眾不同?下面我們就來簡(jiǎn)要解讀2025-02-19如何在Linux環(huán)境下制作 Win11裝機(jī)U盤?
一直用的linux辦公,想要將筆記本電腦從 Linux 系統(tǒng)切換回 Windows 11,我們可以制作一個(gè)win11裝機(jī)u盤,詳細(xì)如下2025-02-17Rsnapshot怎么用? 基于Rsync的強(qiáng)大Linux備份工具使用指南
Rsnapshot 不僅可以備份本地文件,還能通過 SSH 備份遠(yuǎn)程文件,接下來詳細(xì)介紹如何安裝、配置和使用 Rsnapshot,包括創(chuàng)建每小時(shí)、每天、每周和每月的本地備份,以及如何進(jìn)2025-02-06Linux Kernel 6.13發(fā)布:附更新內(nèi)容及新特性解讀
Linux 內(nèi)核 6.13 正式發(fā)布,新版本引入了惰性搶占支持,簡(jiǎn)化內(nèi)核搶占邏輯,通過減少與調(diào)度器相關(guān)的調(diào)用次數(shù),讓內(nèi)核在運(yùn)行時(shí)表現(xiàn)更優(yōu),從而提高效率2025-01-23五大特性引領(lǐng)創(chuàng)新! 深度操作系統(tǒng) deepin 25 Preview預(yù)覽版發(fā)布
今日,深度操作系統(tǒng)正式推出deepin 25 Preview版本,該版本集成了五大核心特性:磐石系統(tǒng)、全新DDE、Treeland窗口合成器、AI For OS以及Distrobox子系統(tǒng)2025-01-18Linux Mint Xia 22.1重磅發(fā)布: 重要更新一覽
Beta 版 Linux Mint“Xia” 22.1 發(fā)布,新版本基于 Ubuntu 24.04,內(nèi)核版本為 Linux 6.8,這次更新帶來了諸多優(yōu)化和改進(jìn),進(jìn)一步鞏固了 Mint 在 Linux 桌面操作系統(tǒng)領(lǐng)域的2025-01-16LinuxMint怎么安裝? Linux Mint22下載安裝圖文教程
Linux Mint22發(fā)布以后,有很多新功能,很多朋友想要下載并安裝,該怎么操作呢?下面我們就來看看詳細(xì)安裝指南2025-01-16