日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

通过零拷贝实现高效的数据传输(操作系统)

發(fā)布時(shí)間:2023/12/19 windows 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 通过零拷贝实现高效的数据传输(操作系统) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

許多Web應(yīng)用程序提供大量靜態(tài)內(nèi)容,這相當(dāng)于從磁盤(pán)讀取數(shù)據(jù)并將完全相同的數(shù)據(jù)寫(xiě)回到響應(yīng)套接字。此活動(dòng)似乎只需要相對(duì)較少的CPU活動(dòng),但效率有點(diǎn)低下:內(nèi)核從磁盤(pán)讀取數(shù)據(jù)并將其跨越內(nèi)核用戶邊界推送到應(yīng)用程序,然后應(yīng)用程序?qū)⑵渫苹氐絻?nèi)核用戶邊界寫(xiě)出到插座。實(shí)際上,應(yīng)用程序作為一個(gè)低效的媒介,將數(shù)據(jù)從磁盤(pán)文件獲取到套接字。

每次數(shù)據(jù)遍歷用戶內(nèi)核邊界時(shí),都必須復(fù)制它,這會(huì)消耗CPU周期和內(nèi)存帶寬。幸運(yùn)的是,您可以通過(guò)一種名為 - 足夠恰當(dāng) -?零拷貝的技術(shù)來(lái)消除這些副本使用零拷貝請(qǐng)求的應(yīng)用程序,內(nèi)核將數(shù)據(jù)直接從磁盤(pán)文件復(fù)制到套接字,而不通過(guò)應(yīng)用程序。零拷貝大大提高了應(yīng)用程序的性能,并減少了內(nèi)核和用戶模式之間的上下文切換次數(shù)。

Java類(lèi)庫(kù)通過(guò)transferTo()in方法在?Linux和UNIX系統(tǒng)上支持零拷貝java.nio.channels.FileChannel您可以使用該transferTo()方法將字節(jié)從其調(diào)用的通道直接傳輸?shù)搅硪粋€(gè)可寫(xiě)字節(jié)通道,而不需要數(shù)據(jù)流經(jīng)應(yīng)用程序。本文首先演示通過(guò)傳統(tǒng)的復(fù)制語(yǔ)義完成簡(jiǎn)單文件傳輸所帶來(lái)的開(kāi)銷(xiāo),然后展示如何使用零復(fù)制技術(shù)?transferTo()實(shí)現(xiàn)更好的性能。

日期轉(zhuǎn)移:傳統(tǒng)方法

考慮從文件讀取并通過(guò)網(wǎng)絡(luò)將數(shù)據(jù)傳輸?shù)搅硪粋€(gè)程序的場(chǎng)景。(本場(chǎng)景描述了許多服務(wù)器應(yīng)用程序的行為,包括提供靜態(tài)內(nèi)容的Web應(yīng)用程序,FTP服務(wù)器,郵件服務(wù)器等等)。操作的核心在清單1中的兩個(gè)調(diào)用中(請(qǐng)參見(jiàn)下載以獲取指向完整的示例代碼):

清單1.將文件中的字節(jié)復(fù)制到套接字
12File.read(fileDesc, buf, len);Socket.send(socket, buf, len);

雖然清單1在概念上很簡(jiǎn)單,但在內(nèi)部,復(fù)制操作需要在用戶模式和內(nèi)核模式之間切換四次上下文,并且在操作完成之前將數(shù)據(jù)復(fù)制四次。圖1顯示了數(shù)據(jù)如何從文件內(nèi)部移動(dòng)到套接字:

圖1.傳統(tǒng)數(shù)據(jù)復(fù)制方法

圖2顯示了上下文切換:

圖2.傳統(tǒng)的上下文切換

涉及的步驟是:

  • read()調(diào)用導(dǎo)致從用戶模式到內(nèi)核模式的上下文切換(參見(jiàn)圖2)。內(nèi)部sys_read()發(fā)布(或等效)以從文件中讀取數(shù)據(jù)。第一個(gè)副本(見(jiàn)圖1)由直接內(nèi)存訪問(wèn)(DMA)引擎執(zhí)行,該引擎從磁盤(pán)讀取文件內(nèi)容并將其存儲(chǔ)到內(nèi)核地址空間緩沖區(qū)中。
  • 所請(qǐng)求的數(shù)據(jù)量從讀緩沖區(qū)復(fù)制到用戶緩沖區(qū)中,然后read()調(diào)用返回。調(diào)用返回導(dǎo)致另一個(gè)從內(nèi)核切換到用戶模式的上下文。現(xiàn)在數(shù)據(jù)存儲(chǔ)在用戶地址空間緩沖區(qū)中。
  • send()插座調(diào)用導(dǎo)致從用戶模式到內(nèi)核模式的上下文切換。執(zhí)行第三個(gè)副本,將數(shù)據(jù)再次放入內(nèi)核地址空間緩沖區(qū)。但是,這一次,數(shù)據(jù)被放入不同的緩沖區(qū),一個(gè)與目標(biāo)套接字關(guān)聯(lián)的緩沖區(qū)。
  • send()系統(tǒng)調(diào)用返回,創(chuàng)造了第四上下文切換。獨(dú)立和異步地,DMA引擎將數(shù)據(jù)從內(nèi)核緩沖區(qū)傳遞到協(xié)議引擎時(shí)發(fā)生第四次復(fù)制。
  • 使用中間內(nèi)核緩沖區(qū)(而不是直接將數(shù)據(jù)傳輸?shù)接脩艟彌_區(qū)中)可能看起來(lái)效率低下。但是,中間內(nèi)核緩沖區(qū)被引入到進(jìn)程中以提高性能。在應(yīng)用程序沒(méi)有要求與內(nèi)核緩沖區(qū)一樣多的數(shù)據(jù)時(shí),在讀取端使用中間緩沖區(qū)允許內(nèi)核緩沖區(qū)充當(dāng)“預(yù)讀緩存”。當(dāng)請(qǐng)求的數(shù)據(jù)量小于內(nèi)核緩沖區(qū)大小時(shí),這會(huì)顯著提高性能。寫(xiě)入側(cè)的中間緩沖區(qū)允許寫(xiě)入異步完成。

    不幸的是,如果所請(qǐng)求數(shù)據(jù)的大小遠(yuǎn)遠(yuǎn)大于內(nèi)核緩沖區(qū)大小,這種方法本身可能會(huì)成為性能瓶頸。在磁盤(pán),內(nèi)核緩沖區(qū)和用戶緩沖區(qū)最終傳送到應(yīng)用程序之前,數(shù)據(jù)被復(fù)制多次。

    零拷貝通過(guò)消除這些冗余數(shù)據(jù)副本來(lái)提高性能。

    數(shù)據(jù)傳輸:零拷貝方法

    如果您重新檢查傳統(tǒng)方案,您會(huì)注意到第二個(gè)和第三個(gè)數(shù)據(jù)副本實(shí)際上不是必需的。應(yīng)用程序除了緩存數(shù)據(jù)并將其傳回到套接字緩沖區(qū)之外別無(wú)其他。相反,數(shù)據(jù)可以直接從讀緩沖區(qū)傳輸?shù)教捉幼志彌_區(qū)。transferTo()?方法可以讓你做到這一點(diǎn)。清單2顯示了以下方法的簽名?transferTo()

    清單2.?transferTo()?方法
    1public void transferTo(long position, long count, WritableByteChannel target);

    transferTo()方法將數(shù)據(jù)從文件通道傳輸?shù)浇o定的可寫(xiě)字節(jié)通道。在內(nèi)部,它取決于底層操作系統(tǒng)對(duì)零拷貝的支持;?在UNIX和各種Linux中,這個(gè)調(diào)用被路由到sendfile()?系統(tǒng)調(diào)用,如清單3所示,它將數(shù)據(jù)從一個(gè)文件描述符傳輸?shù)搅硪粋€(gè)文件描述符:

    清單3.?sendfile()系統(tǒng)調(diào)用
    12#include <sys/socket.h>ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

    清單1中的file.read()socket.send()?調(diào)用的動(dòng)作可以被一個(gè)調(diào)用所取代?,如清單4所示:transferTo()

    清單4.使用?transferTo()將數(shù)據(jù)從磁盤(pán)文件復(fù)制到套接字
    1transferTo(position, count, writableChannel);

    圖3顯示了transferTo()使用方法時(shí)的數(shù)據(jù)路徑

    圖3.使用數(shù)據(jù)拷貝?transferTo()

    圖4顯示了transferTo()?使用方法時(shí)的上下文切換

    圖4.用上下文切換?transferTo()

    transferTo()清單4使用時(shí)采取的步驟如下

  • transferTo()方法使得文件內(nèi)容被DMA引擎復(fù)制到讀取緩沖器中。然后數(shù)據(jù)被內(nèi)核復(fù)制到與輸出套接字關(guān)聯(lián)的內(nèi)核緩沖區(qū)中。
  • 第三次復(fù)制發(fā)生在DMA引擎將數(shù)據(jù)從內(nèi)核套接字緩沖區(qū)傳遞到協(xié)議引擎時(shí)發(fā)生。
  • 這是一個(gè)改進(jìn):我們已將上下文切換次數(shù)從四次減少到兩次,并將數(shù)據(jù)副本數(shù)量從四個(gè)減少到三個(gè)(其中只有一個(gè)涉及CPU)。但是,這還沒(méi)有讓我們達(dá)到零拷貝的目標(biāo)。如果底層網(wǎng)絡(luò)接口卡支持收集操作,我們可以進(jìn)一步減少內(nèi)核所做的數(shù)據(jù)復(fù)制在Linux內(nèi)核2.4和更高版本中,套接字緩沖區(qū)描述符已被修改以適應(yīng)此要求。這種方法不僅減少了多個(gè)上下文切換,還消除了需要CPU參與的重復(fù)數(shù)據(jù)副本。用戶端使用率仍然保持不變,但內(nèi)在因素已發(fā)生變化:

  • transferTo()方法使文件內(nèi)容被DMA引擎復(fù)制到內(nèi)核緩沖區(qū)中。
  • 沒(méi)有數(shù)據(jù)被復(fù)制到套接字緩沖區(qū)中。相反,只有包含有關(guān)數(shù)據(jù)位置和長(zhǎng)度信息的描述符才會(huì)附加到套接字緩沖區(qū)。DMA引擎直接將數(shù)據(jù)從內(nèi)核緩沖區(qū)傳遞到協(xié)議引擎,從而消除了剩余的最終CPU副本。
  • 圖5顯示了使用transferTo()收集操作的數(shù)據(jù)副本

    圖5.?transferTo()使用收集操作時(shí)的數(shù)據(jù)拷貝

    建立一個(gè)文件服務(wù)器

    現(xiàn)在讓我們將零拷貝付諸實(shí)踐,使用在客戶端和服務(wù)器之間傳輸文件的相同示例(請(qǐng)參閱下載以獲取示例代碼)。TraditionalClient.java并?TraditionalServer.java基于傳統(tǒng)的復(fù)制語(yǔ)義,使用File.read()Socket.send()TraditionalServer.java是一個(gè)服務(wù)器程序,它偵聽(tīng)特定端口以供客戶端連接,然后從套接字一次讀取4K字節(jié)的數(shù)據(jù)。TraditionalClient.java連接到服務(wù)器,File.read()從文件讀取(使用)4K字節(jié)的數(shù)據(jù),并socket.send()通過(guò)套接字將內(nèi)容發(fā)送(使用)到服務(wù)器。

    同樣,TransferToServer.java并?TransferToClient.java執(zhí)行相同的功能,而是使用transferTo()方法(并進(jìn)而sendfile()系統(tǒng)調(diào)用)將文件從服務(wù)器傳輸?shù)娇蛻舳恕?/span>

    性能比較

    我們?cè)谶\(yùn)行2.6內(nèi)核的Linux系統(tǒng)上執(zhí)行了示例程序,并測(cè)量了傳統(tǒng)方法和transferTo()不同尺寸方法的運(yùn)行時(shí)間(以毫秒為單位)表1顯示了結(jié)果:

    表1.性能比較:傳統(tǒng)方法與零拷貝
    文件大小正常文件傳輸(毫秒)transferTo(ms)

    正如您所看到的,transferTo()與傳統(tǒng)方法相比API將時(shí)間縮短了約65%。這對(duì)于大量將數(shù)據(jù)從一個(gè)I / O通道復(fù)制到另一個(gè)I / O通道的應(yīng)用程序(如Web服務(wù)器)具有顯著提高性能的潛力。

    概要

    transferTo()與從一個(gè)通道讀取數(shù)據(jù)并將相同的數(shù)據(jù)寫(xiě)入另一個(gè)通道相比,我們已經(jīng)證明了使用它的性能優(yōu)勢(shì)?中間緩沖區(qū)副本 - 即使是隱藏在內(nèi)核中的副本 - 可能會(huì)產(chǎn)生可衡量的成本。在通道間大量復(fù)制數(shù)據(jù)的應(yīng)用程序中,零復(fù)制技術(shù)可以顯著提高性能。

    可下載的資源

    相關(guān)主題

    • 零拷貝I:用戶模式透視




    總結(jié)

    以上是生活随笔為你收集整理的通过零拷贝实现高效的数据传输(操作系统)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。