日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

圖文詳解io_uring高性能異步IO架構(原理篇)

來源: 責編: 時間:2024-01-02 09:32:02 236觀看
導讀說到高性能網絡編程,我們第一時間想到的是epoll機制,epoll很長一段時間統治著整個網絡編程江湖,然而io_uring的出現,似乎在撼動epoll的統治地位,今天我們來揭開io_uring的神秘面紗。1.io_uring簡介io_uring是一個Linux內核

說到高性能網絡編程,我們第一時間想到的是epoll機制,epoll很長一段時間統治著整個網絡編程江湖,然而io_uring的出現,似乎在撼動epoll的統治地位,今天我們來揭開io_uring的神秘面紗。EU628資訊網——每日最新資訊28at.com

1.io_uring簡介

io_uring是一個Linux內核的異步I/O框架,它提供了高性能的異步I/O操作,io_uring的目標是通過減少系統調用和上下文切換的開銷來提高I/O操作的性能。EU628資訊網——每日最新資訊28at.com

io_uring通過使用環形緩沖區和事件驅動的方式來實現高效的異步I/O操作。EU628資訊網——每日最新資訊28at.com

io_uring的設計使得應用程序可以同時處理大量的I/O操作,從而提高系統的吞吐量和響應速度。EU628資訊網——每日最新資訊28at.com

2.io_uring實現原理

io_uring整體架構如下:EU628資訊網——每日最新資訊28at.com

圖片圖片EU628資訊網——每日最新資訊28at.com

2.1基礎概念

  • SQE:提交隊列項,表示IO請求。
  • CQE:完成隊列項,表示IO請求結果。
  • SQ:Submission Queue,提交隊列,用于存儲SQE的數組。
  • CQ:Completion Queue,完成隊列,用于存儲CQE的數組。
  • SQ Ring:SQ環形緩沖區,包含SQ,頭部索引(head),尾部索引(tail),隊列大小等信息。
  • CQ Ring:CQ環形緩沖區,包含SQ,頭部索引(head),尾部索引(tail),隊列大小等信息。
  • SQ線程:內核輔助線程,用于從SQ隊列獲取SQE,并提交給內核處理,并將IO請求結果生成CQE存儲在CQ隊列。

2.2 io_uring系統調用

  • io_uring_setup():用于初始化io_uring環境,創建io_uring實例。
  • io_uring_enter():用于提交和等待io_uring操作的系統調用,可以指定提交的操作數量和等待的超時時間。
  • io_uring_register():用于注冊文件描述符或事件文件描述符到io_uring實例中,以便進行I/O操作。

2.3 liburing庫

liburing是一個用于Linux的用戶空間庫,用于利用io_uring接口進行高性能的異步I/O操作,它提供了一組函數和數據結構,使開發者能夠更方便地使用io_uring接口。EU628資訊網——每日最新資訊28at.com

  • io_uring_queue_init:初始化一個io_uring隊列。
  • io_uring_register:將文件描述符注冊到io_uring隊列中。
  • io_uring_prep_read:準備一個讀取操作。
  • io_uring_prep_write:準備一個寫入操作。
  • io_uring_submit:提交一個或多個操作到io_uring隊列中。
  • io_uring_wait_cqe:等待一個完成的操作。
  • io_uring_cqe_seen:標記一個完成的操作已經被處理。
  • io_uring_queue_exit:關閉并釋放io_uring隊列。

2.4 工作流程

  1. 創建io_uring對象:首先,需要創建一個io_uring對象,可以使用io_uring_setup()函數來完成。
  2. 準備I/O請求:在進行I/O操作之前,需要準備相關的I/O請求。可以使用io_uring_prep_XXX()系列函數來準備不同類型的I/O請求,例如io_uring_prep_read()用于讀取數據,io_uring_prep_write()用于寫入數據。
  3. 提交I/O請求:準備好I/O請求后,可以使用io_uring_submit()函數將請求提交給內核,內核會將這些請求放入一個隊列中,等待執行。
  4. 等待IO請求完成:可以使用io_uring_wait_cqe()函數來等待I/O請求的完成,一旦請求完成,內核會將完成事件放入一個完成隊列中。
  5. 獲取IO請求結果:可以使用io_uring_peek_cqe()函數來獲取完成隊列中的完成事件。然后,可以通過事件的信息來處理完成的I/O請求,例如讀取數據或者處理錯誤。
  6. 釋放IO請求結果:獲取完IO請求結果,使用io_uring_cqe_seen()函數來釋放IO請求結果,以便內核可以繼續使用。
  7. 重復執行:可以重復執行上述步驟,以處理更多的I/O請求。

3.內核實現

3.1 創建io_uring對象

圖片圖片EU628資訊網——每日最新資訊28at.com

用戶程序通過io_uring_setup系統調用創建和初始化io_uring對象,io_uring對象對應于struct io_ring_ctx結構體對象。EU628資訊網——每日最新資訊28at.com

io_uring_setup主要工作:EU628資訊網——每日最新資訊28at.com

  • 創建struct io_ring_ctx對象并初始化。
  • 創建struct io_urings對象并初始化,注意此時已完成CQ和所有CQE創建。
  • 創建SQ和所有SQE并初始化。
  • 如果struct io_ring_ctx對象flags參數設置IORING_SETUP_SQPOLL,則創建SQ線程。

3.2 fd綁定io_uring對象

圖片圖片EU628資訊網——每日最新資訊28at.com

已創建的io_ring對象需要和fd進行綁定, 以便能夠通過fd找到io_uring對象,創建一個新的file,file private_data成員指向io_ring對象,申請一個未使用的文件描述符fd,fd映射至file,并存儲在進程已打開文件表中。EU628資訊網——每日最新資訊28at.com

注意:mmap內存映射需要用到該fd。EU628資訊網——每日最新資訊28at.com

3.3 io_uring對象內存映射

圖片圖片EU628資訊網——每日最新資訊28at.com

通過io_uring_setup系統調用創建完io_uring對象后,用戶程序還不能直接訪問io_uring對象,此時用戶程序需要通過mmap函數將io_uring對象SQ,CQ以及head和tail等相關內存空間映射出來。EU628資訊網——每日最新資訊28at.com

完成mmap內存映射后,io_uring對象相關內存空間成為用戶程序和內核共享內存空間,用戶程序可以直接訪問io_uring對象,不再需要通過執行系統調用訪問,很大程度上提高了系統性能。EU628資訊網——每日最新資訊28at.com

3.4 提交IO請求EU628資訊網——每日最新資訊28at.com

圖片圖片EU628資訊網——每日最新資訊28at.com

SQ Ring中有兩個成員head(頭部索引)和tail(尾部索引),頭部索引指向SQ隊列第一個已提交IO請求,尾部索引指向SQ下一個空閑SQE。EU628資訊網——每日最新資訊28at.com

提交IO請求,只需要將tail指向的SQE填充IO請求信息,并讓tail自增1,指向下一個空閑SQE。EU628資訊網——每日最新資訊28at.com

注意:head和tail不是直接指向SQ數組,而是需要通過head&mask和tail &mask操作指向SQ數組,mask數組為數組長度減1,因為數組有固定大小,所以需要通過&mask方式防止越界訪問數組,這種方式可以讓數組形成一個環形緩沖區。EU628資訊網——每日最新資訊28at.com

3.5 等待IO請求完成EU628資訊網——每日最新資訊28at.com

圖片圖片EU628資訊網——每日最新資訊28at.com

IO請求的處理有兩種方式:EU628資訊網——每日最新資訊28at.com

  • 方式1:SQ線程從SQ隊列中獲取SQE(已提交IO請求),并發送給內核處理。
  • 方式2:用戶程序通過io_uring_enter系統調用從SQ隊列中獲取SQE(已提交IO請求),并發送給內核處理。

從SQ隊列獲取SQE只需要獲取SQ Ring head指向的SQE,并讓head自增指向下一個SQE即可。EU628資訊網——每日最新資訊28at.com

圖片圖片EU628資訊網——每日最新資訊28at.com

內核處理完IO請求后,SQ線程會申請CQ Ring tail指向的CQE存儲IO請求結果,tail自增1指向下一個空閑CQE。EU628資訊網——每日最新資訊28at.com

3.6 獲取IO請求結果

圖片圖片EU628資訊網——每日最新資訊28at.com

用戶程序通過判斷CQ Ring head和tail之間的差值,可以檢測到是否有已完成IO請求,如果有已完成IO請求(CQE),獲取CQ Ring head指向CQE,獲取IO請求結果。EU628資訊網——每日最新資訊28at.com

3.7 釋放已完成IO請求

釋放已完成IO請求只需要將CQ Ring head指針自增1指向下一個CQE即可,這樣做的目的是防止重復獲取IO請求結果。EU628資訊網——每日最新資訊28at.com

io_uring為什么高效?EU628資訊網——每日最新資訊28at.com

核心原因:io_uring通過mmap內存映射大大減少了系統調用,在高并發場景下,系統調用非常損耗系統性能。EU628資訊網——每日最新資訊28at.com

其他原因:EU628資訊網——每日最新資訊28at.com

  • 減少拷貝:io_uring通過共享內存減少用戶程序和內核數據拷貝。
  • 批量操作:io_uring支持批量操作,一次性可以提交多個I/O請求,減少系統調用的次數,提高系統效率。
  • 無鎖環形隊列:io_uring采用無鎖隊列實現用戶程序與內核對共享內存的高效訪問。

本文鏈接:http://www.www897cc.com/showinfo-26-55364-0.html圖文詳解io_uring高性能異步IO架構(原理篇)

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 圖文詳解io_uring高性能異步IO架構(原理篇)

下一篇: 用分布式系統思考團隊管理

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 平乡县| 德昌县| 通榆县| 玛多县| 新丰县| 昭苏县| 三门县| 饶阳县| 镇康县| 东宁县| 庆安县| 乡城县| 临清市| 江川县| 绥滨县| 巩留县| 克东县| 九江县| 榕江县| 沽源县| 德化县| 南宁市| 昭通市| 自贡市| 浑源县| 宁河县| 松阳县| 焉耆| 岐山县| 凯里市| 湖南省| 即墨市| 富锦市| 疏附县| 山阳县| 湘乡市| 扎囊县| 买车| 民县| 澄江县| 嘉峪关市|