偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

零拷貝技術(shù):如何減少 CPU 開銷提升 I/O 性能?

系統(tǒng) 其他OS
在實際場景中,我們可以使用sendfile發(fā)送靜態(tài)文件,比如nginx就支持這種配置;可以通過mmap來映射日志文件數(shù)據(jù)到用戶空間,寫完后通過內(nèi)核將數(shù)據(jù)刷到磁盤,提升寫入性能。比較優(yōu)秀的使用者還有kafka,其也是通過零拷貝提升其數(shù)據(jù)傳輸能力。

0.引言

在高并發(fā)場景下,傳統(tǒng)的I/O操作需要進行多次數(shù)據(jù)拷貝,很容易成為性能瓶頸。而零拷貝技術(shù)(Zero-Copy)通過消除冗余拷貝,讓系統(tǒng)輕松實現(xiàn)百萬級吞吐(如Kafka)。本文將從內(nèi)核原理、API實現(xiàn)到實戰(zhàn)應用,徹底解析這項關(guān)鍵技術(shù)。

1.零拷貝原理

零拷貝是一種高效的數(shù)據(jù)傳輸技術(shù),其主要目的在于減少數(shù)據(jù)的拷貝次數(shù)來提高性能,接下來我們來看其實現(xiàn)原理。

要理解零拷貝的原理首先要理解傳統(tǒng)的數(shù)據(jù)傳輸過程,也就是我們之前說的read和write流程,我們來梳理一下(以讀取磁盤數(shù)據(jù)通過網(wǎng)絡發(fā)送為例),用戶調(diào)用read系統(tǒng)調(diào)用來請求文件數(shù)據(jù),此時CPU需要切換到內(nèi)核態(tài),然后通過DMA將磁盤數(shù)據(jù)拷貝到內(nèi)核空間中,然后再將內(nèi)核緩沖區(qū)數(shù)據(jù)拷貝到用戶空間緩沖區(qū)中,之后CPU切換回用戶態(tài);對于寫來說,用戶調(diào)用write系統(tǒng)調(diào)用,從用戶態(tài)切換到內(nèi)核態(tài),然后將數(shù)據(jù)從用戶緩沖求拷貝到Socket關(guān)聯(lián)的緩沖區(qū),然后數(shù)據(jù)由DMA傳送只網(wǎng)卡緩沖區(qū),然后返回,從內(nèi)核態(tài)切換至用戶態(tài)。

圖片圖片

有了對傳統(tǒng)數(shù)據(jù)傳輸流程的介紹,我們接下來來看零拷貝的相同操作的流程,用戶進程發(fā)起sendfile系統(tǒng)調(diào)用,提高DMA拷貝將數(shù)據(jù)拷貝到內(nèi)核緩沖區(qū),然后把內(nèi)核緩沖區(qū)數(shù)據(jù)拷貝到網(wǎng)卡,把文件描述信息拷貝到socket緩沖區(qū),然后切換回用戶態(tài)。

圖片

有了上面兩個流程的對比,我們可以理解,其實零拷貝(指的是消除了內(nèi)核到用戶空間的數(shù)據(jù)拷貝)就是減少了數(shù)據(jù)的拷貝和用戶-內(nèi)核空間的切換。

2.零拷貝接口實現(xiàn)(代碼均基于Linux 5.10)

2.1 sendfile

2.1.1 函數(shù)定義

sendfile用于在兩個文件描述符之間傳遞數(shù)據(jù)。

#include <sys/sendfile.h>
//out_fd:輸出文件描述符,通常為套接字描述符。
//in_fd:輸入文件描述符,必須是一個支持 mmap() 操作的文件描述符。
//offset:指定從文件的哪個偏移量開始讀取數(shù)據(jù),如果為 NULL,則從當前文件指針位置開始。
//count:要傳輸?shù)臄?shù)據(jù)長度。
//sendfile() 成功返回實際傳輸?shù)淖止?jié)數(shù),失敗返回 -1。
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
2.1.2 函數(shù)源碼解析

sendfile主要函數(shù)為do_sendfile,而do_sendfile中主要函數(shù)為

splice_direct_to_actor,接下來我們對其進行流程梳理如下,其通過內(nèi)部管道消除了向用戶空間的拷貝。

圖片圖片

2.2 mmap

2.2.1 函數(shù)定義

mmap用于申請一段內(nèi)存空間,將內(nèi)核緩沖區(qū)數(shù)據(jù)映射到用戶空間。

#include <sys/mman.h>
//addr:指定映射的起始地址,通常設(shè)為 NULL,由系統(tǒng)自動分配。
//length:映射的長度。
//prot:映射區(qū)域的保護方式,如 PROT_READ(可讀)、PROT_WRITE(可寫)等。
//flags:映射的標志,如 MAP_SHARED(共享映射)、MAP_PRIVATE(私有映射)等。
//fd:要映射的文件描述符。
//offset:映射的起始偏移量。
void *mmap(void *addr, size_t length, int prot, int flags,
                  int fd, off_t offset);
int munmap(void *addr, size_t length);

圖片圖片

2.2.2 函數(shù)源碼解析

mmap中主要調(diào)用為ksys_mmap_pgoff,最終會落到do_mmap函數(shù),其整體流程如下,通過多次檢測和惰性分配以及權(quán)限分離來實現(xiàn):

圖片圖片

2.3 splice

2.3.1 函數(shù)定義

splice用于在兩個文件描述符之間移動數(shù)據(jù)。

#include <fcntl.h>
//fd_in:輸入文件描述符。
//off_in:輸入文件的偏移量指針。
//fd_out:輸出文件描述符。
//off_out:輸出文件的偏移量指針。
//len:要傳輸?shù)臄?shù)據(jù)長度。
//flags:傳輸標志,如 SPLICE_F_MOVE(嘗試移動數(shù)據(jù))、SPLICE_F_NONBLOCK(非阻塞操作)等。
ssize_t splice(int fd_in, loff_t *off_in, int fd_out,
               loff_t *off_out, size_t len, unsigned int flags);
2.3.2 源碼分析

其實現(xiàn)也是依賴管道緩沖區(qū),通過內(nèi)核區(qū)創(chuàng)建和轉(zhuǎn)移所有權(quán)避免了向用戶空間拷貝。

2.4 tee

2.4.1 函數(shù)定義

tee用于在兩個管道描述符之間復制數(shù)據(jù),和splice差異存在于一個是復制一個是移動,且tee只支持管道。

#include <fcntl.h>
//out_fd : 待寫入內(nèi)容的文件描述符
//in_fd : 待讀出內(nèi)容的文件描述符
//len : 需要復制的字節(jié)數(shù)
//flags : 選項
//返回值:成功:返回在兩個文件描述符之間復制的字節(jié)數(shù);沒有數(shù)據(jù):返回0
ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags);

2.4.2 實現(xiàn)分析

和splice類似,只不過一個是移交所有權(quán),一個是增加引用。

3.實際應用以及分析

在實際場景中,我們可以使用sendfile發(fā)送靜態(tài)文件,比如nginx就支持這種配置;可以通過mmap來映射日志文件數(shù)據(jù)到用戶空間,寫完后通過內(nèi)核將數(shù)據(jù)刷到磁盤,提升寫入性能。比較優(yōu)秀的使用者還有kafka,其也是通過零拷貝提升其數(shù)據(jù)傳輸能力。

4.總結(jié)

本文介紹了零拷貝的原理、相關(guān)接口實現(xiàn)和一些實際例子,下一屆將繼續(xù)IO系列,IO性能的性能的衡量和監(jiān)控。

責任編輯:武曉燕 來源: 程序員學習隨筆
相關(guān)推薦

2024-04-29 08:15:07

I/OCPU密集型

2025-07-21 02:00:00

2024-09-20 08:36:43

零拷貝數(shù)據(jù)傳輸DMA

2024-12-04 14:45:14

零拷貝技術(shù)CPU 拷貝Zero-copy

2014-07-28 16:47:41

linux性能

2025-10-11 02:11:00

Spring零拷貝磁盤

2020-10-09 17:43:25

計算機CPU技術(shù)

2022-04-23 16:30:22

Linux磁盤性能

2025-07-14 00:20:00

2022-05-05 13:57:43

Buffer設(shè)備MYSQL

2025-06-26 09:15:41

2024-01-29 10:08:11

零拷貝Zero-copyCPU 拷貝

2017-02-09 09:00:14

Linux IO調(diào)度器

2025-08-07 01:00:00

2025-06-16 09:46:06

2020-06-10 08:28:51

Kata容器I

2011-04-11 11:32:29

Oracle分區(qū)表磁盤IO沖突

2023-08-11 08:55:43

OfficeEdge

2024-10-22 08:00:00

2020-11-18 14:27:03

Chrome瀏覽器功能
點贊
收藏

51CTO技術(shù)棧公眾號