日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

io_uring vs epoll ,谁在网络编程领域更胜一筹?

發(fā)布時(shí)間:2024/8/23 63 豆豆
生活随笔 收集整理的這篇文章主要介紹了 io_uring vs epoll ,谁在网络编程领域更胜一筹? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

簡介:從定量分析的角度,通過量化 io_uring 和 epoll 兩種編程框架下的相關(guān)操作的耗時(shí),來分析二者的性能差異。

本文作者:王小光,「高性能存儲技術(shù)SIG」核心成員。

背景

io_uring 在傳統(tǒng)存儲 io 場景已經(jīng)證明其價(jià)值,但 io_uring 不僅支持傳統(tǒng)存儲 io,也支持網(wǎng)絡(luò) io。io_uring 社區(qū)有眾多的開發(fā)者嘗試將 io_uring 用于網(wǎng)絡(luò)應(yīng)用。我們之前也在《你認(rèn)為 io_uring 只適用于存儲 IO?大錯(cuò)特錯(cuò)!》中也探索過 io_uring 在網(wǎng)絡(luò)場景的應(yīng)用及其與傳統(tǒng)網(wǎng)絡(luò)編程基石 epoll 的對比,當(dāng)時(shí)我們的測試結(jié)果顯示在 cpu 漏洞緩解使能的前提下,io_uring 相比于 epoll 可以帶來一定的優(yōu)勢,在 cpu 漏銅緩解未使能時(shí),io_uring 相比于 epoll 沒有優(yōu)勢,可能還會存在性能下降。

在 io_uring 社區(qū),關(guān)于 io_uring 和 epoll 孰優(yōu)孰劣也一直存在爭論,有些開發(fā)者宣稱 io_uring 可以獲得比 epoll 更好的性能,有些開發(fā)者則宣稱二者性能持平或者 io_uring 甚至不如 epoll。相關(guān)的討論非常多,具體可參見如下兩例:

https://github.com/axboe/liburing/issues/189

Wild results, cannot reproduce · Issue #8 · frevib/io_uring-echo-server · GitHub

以上討論從 2020 年 8 月一直持續(xù)到現(xiàn)在,其過程非常長也非常地激烈??梢钥闯?io_uring 和 epoll 在網(wǎng)絡(luò)編程領(lǐng)域孰優(yōu)孰劣目前確實(shí)比較難以達(dá)成共識。

目前很多業(yè)務(wù)想將 io_uring 在網(wǎng)絡(luò)場景應(yīng)用起來,但 io_uring 是否能比 epoll 帶來性能提升,大家或多或少存在些許疑問。為了徹底厘清這個(gè)問題,龍蜥社區(qū)高性能存儲 SIG嘗試從定量分析的角度,通過量化 io_uring 和 epoll 兩種編程框架下的相關(guān)操作的耗時(shí),來分析二者的性能差異。

評估模型

我們?nèi)匀贿x用 echo server 模型進(jìn)行性能評估,server 端采用單線程模型,同時(shí)為公平對比,io_uring 不使用內(nèi)部的 io-wq 機(jī)制(io_uring 在內(nèi)核態(tài)維護(hù)的線程池,可以用來執(zhí)行用戶提交的 io 請求)。epoll 采用 send(2) 和 recv(2) 進(jìn)行數(shù)據(jù)的讀寫操作;而 io_uring 采用 IORING_OP_SEND 和 IORING_OP_RECV 進(jìn)行數(shù)據(jù)的讀寫操作。

結(jié)合 echo server 的模型,我們分析有四個(gè)因素會影響 io_uring 和 epoll 的性能,分別是:

1、系統(tǒng)調(diào)用用戶態(tài)到內(nèi)核態(tài)上下文切換開銷,記為 s

2、系統(tǒng)調(diào)用自身內(nèi)核態(tài)工作邏輯開銷,記為 w

3、io_uring 框架本身開銷,記為 o

4、io_uring 的 batch 量,記為 n,epoll 版 echo server 由于直接調(diào)用 recv(2) 和 send(2), 其 batch 實(shí)際為 1。

同時(shí)在本文中我們僅評估 io_uring 和 epoll 請求讀寫操作的開銷,對于 io_uring 和 epoll 本身的事件通知機(jī)制本身不做衡量,因?yàn)橥ㄟ^ perf 工具分析,讀寫請求本身開銷占據(jù)絕大部分。系統(tǒng)調(diào)用用戶態(tài)到內(nèi)核態(tài)上下文切換開銷可以通過專門的程序進(jìn)行測量,因素 2、3、4 等可以通過衡量內(nèi)核相關(guān)函數(shù)的執(zhí)行時(shí)間進(jìn)行測量,用 bpftrace 進(jìn)行分析。

epoll 版 echo server 開銷度量

從用戶態(tài)視角,send(2) 或者 recv(2) 開銷主要包含兩個(gè)方面,系統(tǒng)調(diào)用用戶態(tài)到內(nèi)核態(tài)上下文切換開銷和系統(tǒng)調(diào)用自身內(nèi)核態(tài)工作邏輯開銷,其中系統(tǒng)調(diào)用本身工作邏輯的開銷,send(2) 和 recv(2) 分別衡量 sys_sendto(), sys_recvfrom() 即可。

由于 epoll 場景下其系統(tǒng)調(diào)用的 batch 為 1,因此 epoll ?模型下收發(fā)請求的平均耗時(shí)為 (s + w)。

io_uring 版 echo server 開銷度量

io_uring 中 io_uring_enter(2) 系統(tǒng)調(diào)用既可以用來提交 sqe,也可以用來 reap cqe,兩種操作混合在一個(gè)系統(tǒng)調(diào)用中,準(zhǔn)確衡量 sqe 的提交收發(fā)請求的耗時(shí)比較困難。簡單起見,我們采用跟蹤 io_submit_sqes() 的開銷來衡量 IORING_OP_SEND 和 IORING_OP_RECV 的開銷,此函數(shù)被 io_uring_enter(2) 所調(diào)用。io_submit_sqes() 包含send(2) 和 revc(2) 內(nèi)核側(cè)工作邏輯開銷,及 io_uring 框架的開銷,記為 t

同時(shí)我們采用 io_uring 的 multi-shot 模式,從而確保 io_submit_sqes() 中的提交的 IORING_OP_SEND 和 IORING_OP_RECV 請求都可以直接完成,而不會用到io_uring的 task-work 機(jī)制。

由于 io_uring 場景下可以 batch 系統(tǒng)調(diào)用的執(zhí)行,因此 io_uirng 模型下收發(fā)請求的平均耗時(shí)為 (s + t) / n。

實(shí)際度量

我們測試環(huán)境 Intel(R) Xeon(R) CPU E5-2682 v4 @ 2.50GHz,衡量 echo server 單鏈接性能數(shù)據(jù)。

用戶態(tài)內(nèi)核態(tài)系統(tǒng)調(diào)用上下文切換開銷

cpu 漏洞對系統(tǒng)調(diào)用用戶態(tài)內(nèi)核態(tài)上下文切換的影響比較大,在我們的測試環(huán)境中:漏銅緩解使能時(shí),系統(tǒng)調(diào)用的上下文切換開銷為 700ns 左右;漏銅緩解未使能時(shí),系統(tǒng)調(diào)用的上下文切換開銷為 230ns 左右。

epoll 模型下 send(2)/recv(2) 內(nèi)核側(cè)開銷

采用bpftrace 腳本分別衡量 sys_sendto()sys_recvfrom() 即可。 bpftrace 腳本如下:

BEGIN {@start = 0;@send_time = 0;@send_count = 0; } kprobe:__sys_sendto /comm == "epoll_echo_serv"/ {@start = nsecs; } kprobe:__sys_recvfrom /comm == "epoll_echo_serv"/ {@start = nsecs; } kretprobe:__sys_sendto /comm == "epoll_echo_serv"/ { if (@start > 0) {@delay = nsecs - @start;@send_time = @delay + @send_time;@send_count = @send_count + 1;} } kretprobe:__sys_recvfrom /comm == "epoll_echo_serv"/ { if (@start > 0) {@delay = nsecs - @start;@send_time = @delay + @send_time;@send_count = @send_count + 1;} } interval:s:5 { printf("time: %llu\n", @send_time / @send_count);@send_time = 0;@send_count = 0; }

在單連接,包大小 16 字節(jié)場景下,epoll 版的 echo_server 的 tps 在 1000 左右,其 recv(2) 和 send(2) 的內(nèi)核側(cè)邏輯平均開銷如下:

time: 1489、time: 1492、time: 1484、time: 1491、time: 1499、time: 1505、time: 1512、time: 1528、time: 1493、time: 1509、time: 1495、time: 1499、time: 1544

從上述數(shù)據(jù)可以看出,send(2) 和 recv(2) 的內(nèi)核側(cè)平均開銷在1500ns左右,因此:

1) cpu 漏洞緩解,send(2) 和 recv(2) 的平均開銷為 s=700ns,w=1500ns,總共 (s+w) = 2200ns

2) cpu 漏洞為緩解,send(2) 和 recv(2) 的平均開銷為 s=230ns,w=1500ns,總共 (s+w) = 1730ns。

io_uring 模型下 io_uring_enter(2) 內(nèi)核側(cè)開銷

采用bpftrace 腳本分別衡量 io_submit_sqes() 開銷即可。

BEGIN {@start = 0;@send_time = 0;@send_count = 0; } kprobe:io_submit_sqes /comm == "io_uring_echo_s"/ {@start = nsecs;@send_count = @send_count + arg1; } kretprobe:io_submit_sqes /comm == "io_uring_echo_s"/ { if (@start > 0) {@delay = nsecs - @start;@send_time = @delay + @send_time;} } interval:s:5 { printf("time: %llu\n", @send_time / @send_count);@send_time = 0;@send_count = 0; }

運(yùn)行類似上述 epoll 同樣的測試,數(shù)據(jù)為:

time: 1892、time: 1901、time: 1901、time: 1882、time: 1890、time: 1936、time: 1960、time: 1907、time: 1896、time: 1897、time: 1911、time: 1897、time: 1891、time: 1893、time: 1918、time: 1895、time: 1885

從上述數(shù)據(jù)可以看出,io_submit_sqes() 的內(nèi)核側(cè)平均開銷在 1900ns 左右,注意此時(shí)的batch n=1,且該開銷包括收發(fā)請求的內(nèi)核態(tài)工作邏輯開銷及 io_uring 框架開銷。

1) cpu 漏洞緩解,用戶態(tài)觀察到的 io_uring_enter(2) 平均開銷為 t=1900ns,n=1,s=700ns,總共 (t+s) / n = 2600ns

2) cpu 漏洞未緩解,用戶態(tài)觀察到的 io_uring_enter(2) 的平均開銷為 t=1900ns,n=1,s=230ns,總共 (t+s) / n = 2130ns。

注意由于我們實(shí)際只 trace io_submit_sqes,而 io_uring_enter(2) 系統(tǒng)調(diào)用是調(diào)用 io_submit_sqes 的,因此 io_uring_enter(2) 的實(shí)際開銷是肯定大于 (t+s) / n。

數(shù)據(jù)量化分析

從上述數(shù)據(jù)發(fā)現(xiàn),cpu 漏洞確實(shí)對系統(tǒng)調(diào)用的性能影響較大,尤其對于小數(shù)據(jù)包的場景,我們分別討論下:

cpu 漏洞緩解未使能

epoll: s+w, ?io_uring: (t+s) / n

可以看出在此種情況下,由于 t 大于 w, 即使擴(kuò)大 batch,io_uring 的性能也不如 epoll。

cpu 漏洞緩解使能

epoll: s+w, ?io_uring: (t+s) / n

可以看出在此種情況下,由于 s 比較大,當(dāng) batch 比較低時(shí),io_uring 不如 epoll,但當(dāng) batch 比較大時(shí),io_uring 場景下系統(tǒng)調(diào)用上下文切換開銷被極大攤薄,此時(shí) io_uring 的性能是優(yōu)于 epoll。在我們的實(shí)際測試中,1000連接時(shí),io_uring 的的吞吐要比 epoll 高 10% 左右,基本符合我們的建模。

結(jié)論

從我們的量化分析可以看出 io_uring 與 epoll 孰優(yōu)孰劣完全由評估模型中定義的 4 個(gè)變量決定:

epoll: s + w

io_uring: (t + s) / n

如果某個(gè)變量占主導(dǎo)地位,則性能數(shù)據(jù)會截然不同。舉個(gè)例子,假設(shè)系統(tǒng)調(diào)用上下文切換開銷 s 很大,而且 io_uring batch n 也很大,則 io_uring 在此種場景下的性能肯定是會比 epoll 好;再比如系統(tǒng)內(nèi)核側(cè)開銷 w 很大,此時(shí) io_uring 和 epoll 性能會接近。

因此 io_uring 和 epoll 孰優(yōu)孰劣,取決于其應(yīng)用場景,我們建議的最佳實(shí)踐是基于業(yè)務(wù)真實(shí)網(wǎng)絡(luò)模型,將其簡化為 echo server 模型,運(yùn)行我們的度量腳本,從而可以評估二者在真實(shí)環(huán)境的性能,以指導(dǎo)真實(shí)應(yīng)用開發(fā)。同時(shí)上述度量數(shù)據(jù)也為我們的性能優(yōu)化提供方向,我們可以盡可能的減少某一變量的開銷,從而提高性能,比如可以進(jìn)一步優(yōu)化 io_uring 框架的開銷。

高性能存儲技術(shù)SIG介紹

高性能存儲技術(shù)SIG :致力于存儲棧性能挖掘化,打造標(biāo)準(zhǔn)的高性能存儲技術(shù)軟件棧,推動軟硬件協(xié)同發(fā)展。

原文鏈接
本文為阿里云原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。?

總結(jié)

以上是生活随笔為你收集整理的io_uring vs epoll ,谁在网络编程领域更胜一筹?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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