电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

淺談Linux的零拷貝技術(shù)

瀏覽:217日期:2023-05-12 10:25:40

前言

在Linux系統(tǒng)內(nèi)部緩存和內(nèi)存容量都是有限的,更多的數(shù)據(jù)都是存儲(chǔ)在磁盤中。對(duì)于Web服務(wù)器來說經(jīng)常需要從磁盤中讀取數(shù)據(jù)到內(nèi)存,然后再通過網(wǎng)卡傳輸給用戶

那么這也算一次I O的過程,都知道IO過程中需要狀態(tài)的切換還有一系列拷貝過程,都是要時(shí)間開銷的,那么怎么優(yōu)化用戶態(tài)和內(nèi)核態(tài)的狀態(tài)的切換次數(shù)和各種緩沖區(qū)之間的拷貝次數(shù),也是linux的服務(wù)器實(shí)現(xiàn)高并發(fā)的重要技術(shù)了!

傳統(tǒng)數(shù)據(jù)交互

傳統(tǒng) io 的執(zhí)行流程: 下面將圖左半部分read過程的硬件抽象為磁盤; 圖右半部分write過程的硬件設(shè)為網(wǎng)卡,模擬webserver進(jìn)行一次IO的過程; 方便理解;

  • read:將數(shù)據(jù)從 IO 設(shè)備讀取到內(nèi)核緩存區(qū)中,再將數(shù)據(jù)從內(nèi)核緩沖區(qū)拷貝到用戶緩沖區(qū)
  • write:將數(shù)據(jù)從用戶緩沖區(qū)寫入到內(nèi)核緩沖區(qū)中,再將數(shù)據(jù)從內(nèi)核緩沖區(qū)拷貝到 IO 設(shè)備

read/write 屬于系統(tǒng)調(diào)用 syscall,每一次系統(tǒng)調(diào)用 ,發(fā)生兩次上下文切換

  • 調(diào)用 syscall 從用戶態(tài)切換到內(nèi)核態(tài)
  • syscall 返回從內(nèi)核態(tài)切換到用戶態(tài)

如圖所示,傳統(tǒng) io 的過程中,發(fā)生了4次空間切換 + 4次拷貝

不難看出,傳統(tǒng)模式下的IO,涉及多次空間切換和數(shù)據(jù)冗余拷貝,效率并不高。而零拷貝 Zero-Copy 目的就是降低冗余數(shù)據(jù)拷貝,解放 CPU

  • 減少數(shù)據(jù)在內(nèi)核緩沖區(qū)和用戶緩沖區(qū)之間的冗余拷貝(CPU拷貝)
  • 減少系統(tǒng)調(diào)用導(dǎo)致的空間切換

目前來看,零拷貝技術(shù)的實(shí)現(xiàn)手段主要包括:mmap+write、sendfile、sendfile+DMA、splice

零拷貝

首先解釋一下,零拷貝中的0,指的是CPU級(jí)別的數(shù)據(jù)拷貝(比如內(nèi)核緩沖區(qū)到用戶緩沖區(qū)的拷貝,用戶緩沖區(qū)再到socket緩沖區(qū); 或者內(nèi)核緩沖區(qū)直接到socket緩沖區(qū)的拷貝!),并不是DMA硬件的拷貝,否則數(shù)據(jù)不靠DMA怎么轉(zhuǎn)移呢?

mmap+write

  • 內(nèi)存映射 memory mapping,mmap 是一種內(nèi)存映射文件的方法,即將一個(gè)文件或者其他對(duì)象映射到進(jìn)程的地址空間,實(shí)現(xiàn)文件磁盤地址和進(jìn)程虛擬地址空間中一段虛擬地址的一一映射關(guān)系。

mmap可以充當(dāng)read的功能,將內(nèi)核讀緩沖區(qū)地址與用戶緩沖區(qū)地址進(jìn)行映射,實(shí)現(xiàn)內(nèi)核緩沖區(qū)與用戶緩沖區(qū)的共享。這樣就減少了一次用戶態(tài)和內(nèi)核態(tài)的CPU拷貝。

mmap + write 流程如圖所示,發(fā)生了4次切換 + 2次DMA拷貝 + 1次CPU拷貝

函數(shù)原型

#include <sys/mman.h>// 內(nèi)存映射void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset);/*參數(shù)start:指定映射的虛擬內(nèi)存地址,通常定義為 NULL,由內(nèi)核選定地址length:映射的長(zhǎng)度prot:描述映射內(nèi)存的訪問權(quán)限PROT_EXEC頁面可以被 cpu 執(zhí)行指令組成,PROT_NONE 頁面不能訪問PROT_READ 頁面可讀,PROT_WRITE 頁面可寫,flags:指定映射的類型,MAP_SHARED共享對(duì)象,MAP_PRIVATE私有的,寫時(shí)復(fù)制對(duì)象fd:要進(jìn)行映射的文件句柄offset:文件偏移量*/// 解除映射int munmap(void *addr, size_t length);

例: 發(fā)送方:

// 建立內(nèi)存映射char *pMap = (char*) mmap (NULL, fileInfo.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); send(clientFd, pMap, fileInfo.st_size, 0);// 解除映射munmap(pMap, fileInfo.st_size); 

接收方:

// 使用 mmap 前用使用 ftruncate 來擴(kuò)大文件大小ftruncate(fd, fileSize);char *pMap = (char*) mmap (NULL, fileSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);recvCycle(sfd, pMap, fileSize);munmap(pMap, fileSize);

小結(jié)

mmap充當(dāng)read的功能,進(jìn)行一次完整的IO,減少了傳統(tǒng)方式read數(shù)據(jù)的時(shí)候,從內(nèi)核態(tài)CPU拷貝到用戶態(tài)的這次拷貝; (發(fā)生了4次切換 + 2次DMA拷貝 + 1次CPU拷貝;)

mmap 存在的問題:mmap 對(duì)大文件傳輸有一定優(yōu)勢(shì),但是小文件可能出現(xiàn)碎片,并且在多個(gè)進(jìn)程同時(shí)操作文件時(shí)可能產(chǎn)生引發(fā) coredump 的 signal。

sendfile

mmap+write 方式有一定改進(jìn),但是由系統(tǒng)調(diào)用引起的狀態(tài)切換并沒有減少,因此在 Linux 內(nèi)核2.1版本中引入了 sendfile 系統(tǒng)調(diào)用。

sendfile 在兩個(gè)文件之間通過內(nèi)核直接傳輸數(shù)據(jù),避免了內(nèi)核緩沖區(qū)和用戶緩沖區(qū)之間的數(shù)據(jù)拷貝操作。sendfile 只能用于發(fā)送數(shù)據(jù),不能用于接收數(shù)據(jù)。

sendfile 方式只使用一個(gè)函數(shù)就可以完成之前的 read+write 和 mmap+write 的功能,這樣減少一個(gè)系統(tǒng)調(diào)用(2次狀態(tài)切換),由于數(shù)據(jù)不經(jīng)過用戶緩沖區(qū),因此該數(shù)據(jù)無法被修改。

sendfile 的流程如圖所示, 發(fā)生了2次切換 + 2次DMA拷貝+1次CPU拷貝

sendfile + DMA

linux2.4版本后,對(duì) sendfile 系統(tǒng)調(diào)用進(jìn)行優(yōu)化,配合硬件 DMA,可以直接從內(nèi)核空間緩沖區(qū)中將數(shù)據(jù)拷貝到網(wǎng)卡,徹底省去了CPU拷貝

如圖所示,sendfile + DMA 的過程中發(fā)生了2次切換 + 2次DMA拷貝 + 0次CPU拷貝

sendfile 函數(shù)原型

#include <sys/sendfile.h>ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);/*參數(shù)- out_fd:待寫入內(nèi)容的文件描述符- in_fd:待讀出內(nèi)容的文件描述符- offset:文件偏移量- count:傳輸?shù)淖止?jié)數(shù)*/

例:

發(fā)送方

sendfile(clientFd, fd, 0, fileInfo.st_size);

小結(jié)

早期sendfile : 2次切換 (sendfile后,數(shù)據(jù)不用過用戶層了,導(dǎo)致不能修改了,不過也少了兩次狀態(tài)切換!)+ 2次DMA拷貝(磁盤到內(nèi)核,socket緩沖區(qū)到網(wǎng)卡)+ 1次CPU拷貝(內(nèi)核到socket緩沖區(qū))

改良的sendfile + DMA : 發(fā)生了2次切換 + 2次DMA拷貝(磁盤到內(nèi)核,內(nèi)核直接到網(wǎng)卡) + 0次CPU拷貝

sendfile 存在的問題:無法對(duì)數(shù)據(jù)進(jìn)行修改(數(shù)據(jù)沒上到用戶層,也沒必要,webserver一般都不需要修改,返回的本地的資源!),并且需要硬件層面DMA的支持,并且 sendfile 只能將文件數(shù)據(jù)拷貝到 socketfd,有一定的局限性。

splice

splice 系統(tǒng)調(diào)用在 Linux 2.6 版本引入,不需要硬件支持,并且不再限定于 socket 上,實(shí)現(xiàn)了兩個(gè)普通文件之間的零拷貝

可以在內(nèi)核緩沖區(qū)和 socket 緩沖區(qū)間建立管道來傳輸數(shù)據(jù)避免了兩者之間的 CPU 拷貝操作

函數(shù)原型

#define _GNU_SOURCE #include <fcntl.h>ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);/*返回值;成功返回接收到的字節(jié)數(shù),失敗-1參數(shù)- fd_in:待輸入數(shù)據(jù)的文件描述符。- off_in: 輸入流偏移量。若 fd_in 是管道文件描述符,則設(shè)置為 NULL,表示從當(dāng)前偏移讀入。   否則,off_in 表示從輸入數(shù)據(jù)流的某處開始讀取。- fd_out:待輸出數(shù)據(jù)的文件描述符。- off_out:輸出流偏移量,同上。- len:?jiǎn)未螌懭氲臄?shù)據(jù)長(zhǎng)度,最多65536- flags:0*/

例:web服務(wù)器端代碼: transFile.c:

int fds[2];pipe(fds);int recvLen = 0;//當(dāng)讀到的數(shù)據(jù)量超過文件大小時(shí),即已經(jīng)讀取數(shù)據(jù)完成while(recvLen < fileInfo.st_size){    //將數(shù)據(jù)從服務(wù)器端本地讀到管道    ret = splice(fd, 0, fds[1], 0, 65536, 0);    //將數(shù)據(jù)從管道讀到客戶端    ret = splice(fds[0], 0, clientFd, 0, ret, 0);    //計(jì)算已經(jīng)讀到的數(shù)據(jù)量    recvLen += ret;}

小結(jié)

splice 引入管道機(jī)制,實(shí)現(xiàn)了普通文件之間的0拷貝,突破了僅限于socket的sendfile0拷貝;

splice 存在的問題:它的兩個(gè)文件描述符中有一個(gè)必須是管道設(shè)備

到此這篇關(guān)于淺談Linux的零拷貝技術(shù)的文章就介紹到這了,更多相關(guān)Linux零拷貝技術(shù)內(nèi)容請(qǐng)搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!

標(biāo)簽: Linux
主站蜘蛛池模板: 吨袋包装机|吨包秤|吨包机|集装袋包装机-烟台华恩科技 | 合肥地磅_合肥数控切割机_安徽地磅厂家_合肥世佳电工设备有限公司 | 纸箱网 -纸箱机械|设备|包装纸盒|包装印刷行业门户网站 | 【黄页88网】-B2B电子商务平台,b2b平台免费发布信息网 | 防堵吹扫装置-防堵风压测量装置-电动操作显示器-兴洲仪器 | 丽陂特官网_手机信号屏蔽器_Wifi信号干扰器厂家_学校考场工厂会议室屏蔽仪 | 包装盒厂家_纸盒印刷_礼品盒定制-济南恒印包装有限公司 | 土壤检测仪器_行星式球磨仪_土壤团粒分析仪厂家_山东莱恩德智能科技有限公司 | 干粉砂浆设备-干粉砂浆生产线-干混-石膏-保温砂浆设备生产线-腻子粉设备厂家-国恒机械 | 凝胶成像仪,化学发光凝胶成像系统,凝胶成像分析系统-上海培清科技有限公司 | 塑料薄膜_PP薄膜_聚乙烯薄膜-常州市鑫美新材料包装厂 | 新疆系统集成_新疆系统集成公司_系统集成项目-新疆利成科技 | 防爆电机-高压防爆电机-ybx4电动机厂家-河南省南洋防爆电机有限公司 | 杰恒蠕动泵-蠕动泵专业厂家-19年专注蠕动泵 | 广州展览设计公司_展台设计搭建_展位设计装修公司-众派展览装饰 广州展览制作工厂—[优简]直营展台制作工厂_展会搭建资质齐全 | 小型玉石雕刻机_家用玉雕机_小型万能雕刻机_凡刻雕刻机官网 | Jaeaiot捷易科技-英伟达AI显卡模组/GPU整机服务器供应商 | 蓝米云-专注于高性价比香港/美国VPS云服务器及海外公益型免费虚拟主机 | 我爱古诗词_古诗词名句赏析学习平台 | 知企服务-企业综合服务(ZiKeys.com)-品优低价、种类齐全、过程管理透明、速度快捷高效、放心服务,知企专家! | 耐力板-PC阳光板-PC板-PC耐力板 - 嘉兴赢创实业有限公司 | 外贮压-柜式-悬挂式-七氟丙烷-灭火器-灭火系统-药剂-价格-厂家-IG541-混合气体-贮压-非贮压-超细干粉-自动-灭火装置-气体灭火设备-探火管灭火厂家-东莞汇建消防科技有限公司 | 塑料熔指仪-塑料熔融指数仪-熔体流动速率试验机-广东宏拓仪器科技有限公司 | 打孔器,打孔钳厂家【温州新星德牌五金工具】 | 全温恒温摇床-水浴气浴恒温摇床-光照恒温培养摇床-常州金坛精达仪器制造有限公司 | 土壤养分检测仪_肥料养分检测仪_土壤水分检测仪-山东莱恩德仪器 大型多片锯,圆木多片锯,方木多片锯,板材多片锯-祥富机械有限公司 | 拉力机-万能试验机-材料拉伸试验机-电子拉力机-拉力试验机厂家-冲击试验机-苏州皖仪实验仪器有限公司 | 磁力抛光机_磁力研磨机_磁力去毛刺机-冠古设备厂家|维修|租赁【官网】 | 对辊破碎机-液压双辊式,强力双齿辊,四辊破碎机价格_巩义市金联机械设备生产厂家 | PSI渗透压仪,TPS酸度计,美国CHAI PCR仪,渗透压仪厂家_价格,微生物快速检测仪-华泰和合(北京)商贸有限公司 | 长江船运_国内海运_内贸船运_大件海运|运输_船舶运输价格_钢材船运_内河运输_风电甲板船_游艇运输_航运货代电话_上海交航船运 | 扫地车厂家-山西洗地机-太原电动扫地车「大同朔州吕梁晋中忻州长治晋城洗地机」山西锦力环保科技有限公司 | 注塑机-压铸机-塑料注塑机-卧式注塑机-高速注塑机-单缸注塑机厂家-广东联升精密智能装备科技有限公司 | 消泡剂_水处理消泡剂_切削液消泡剂_涂料消泡剂_有机硅消泡剂_广州中万新材料生产厂家 | 高低温试验箱-模拟高低温试验箱订制-北京普桑达仪器科技有限公司【官网】 | 陕西安玻璃自动感应门-自动重叠门-磁悬浮平开门厂家【捷申达门业】 | 亿诺千企网-企业核心产品贸易| 智能化的检漏仪_气密性测试仪_流量测试仪_流阻阻力测试仪_呼吸管快速检漏仪_连接器防水测试仪_车载镜头测试仪_奥图自动化科技 | SPC工作站-连杆综合检具-表盘气动量仪-内孔缺陷检测仪-杭州朗多检测仪器有限公司 | 酒精检测棒,数显温湿度计,酒安酒精测试仪,酒精检测仪,呼气式酒精检测仪-郑州欧诺仪器有限公司 | 中细软知识产权_专业知识产权解决方案提供商 |