linux2020
一台實體機 (Server),與一台遠端主機 (Client) 透過外部網路互連,並非直接網路線對接或只經過一台交換器
$ sudo vim /etc/default/grub
/etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash isolcpus=0"
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
, 在該行空白後添加 isolcpus=1
, 其中等號右邊為 CPU 核的 index,從 0 開始$ sudo update-grub
update-grub
$taskset -p PID
: 得到十六進位的 bitmask,換算成二進位後每個 set bit 代表與該核具親合$taskset -cp PID
: 得到十進位的版本$taskset -p COREMASK PID
或 $taskset -cp CORELIST PID
Client side: $ ab -n 100000 -c $CONNECTION [-k] http://140.116.aaa.aaa:8081/
, $CONNECTION 為同時連線數量
針對每秒處理 request 數量的部份我們分為有 keep-alive 與沒有 keep-alive 參數來進行
ab command output message info.
With keep-alive parameter
使用 keep-alive 參數時我們針對總數皆為十萬次 request,但改變同時連線的數量來比較:
Number of connection | Number of fail | Requests per second | Time per request (ms 1 conncurrent) |
---|---|---|---|
100 | 0 / 1300 | 2266 / 2025 | 44 / 49 |
300 | 0 / 1200 | 6799 / 6116 | 44 / 49 |
500 | 0 / 1000 | 11336 / 10364 | 44 / 48 |
800 | 0 / 800 | 17517 / 16680 | 46 / 48 |
1000 | 0 / 1000 | 22522 / 20382 | 44 / 49 |
![]() |
Without keep-alive parameter
Number of connection | Number of fail | Requests per second | Time per request (ms 1 conncurrent) |
---|---|---|---|
100 | 0 / 0 | 58642 / 44147 | 2 / 2 |
300 | 0 / 0 | 57408 / 40492 | 5 / 7 |
500 | 0 / 0 | 55248 / 42380 | 9 / 12 |
800 | 0 / 0 | 54008 / 42382 | 15 / 19 |
1000 | 0 / 0 | 52506 / 42158 | 19 / 24 |
![]() |
Plot time consumpsion of do_request function
我們嘗試測量系統處理每一次 request 所需的時間,發現修改後的程式碼時間分布較集中且少
嘗試計算十萬次 request 的時間並取其 99% 信賴區間後的圖形
透過 perf_events
進行測試
Server side: $ sudo perf stat -r 5 ./sehttpd > /dev/null
Client side: $ ab -n 100000 -c 1000 [-k] http://140.116.aaa.aaa:8081/
在這次的實作除了將 epoll 修改成 io_uring,也進行了一些修正:
page-faults
的次數。computed goto
取代,減少 branch-misses
的發生cycles
數及 instructions
數。目前的僅有一台實體機作為 server 的數據,預期會再找其他實體機多測試。
Performance counter stats for './sehttpd' (5 runs):
1,533.19 msec task-clock # 0.113 CPUs utilized ( +- 0.57% )
1,593 context-switches # 0.001 M/sec ( +- 0.87% )
0 cpu-migrations # 0.000 K/sec
1,391 page-faults # 0.907 K/sec ( +- 0.03% )
5,316,634,475 cycles # 3.468 GHz ( +- 0.57% )
5,397,118,059 instructions # 1.02 insn per cycle ( +- 0.36% )
1,031,652,823 branches # 672.880 M/sec ( +- 0.35% )
11,219,837 branch-misses # 1.09% of all branches ( +- 0.65% )
13.63 +- 4.94 seconds time elapsed ( +- 36.26% )
Performance counter stats for './sehttpd' (5 runs):
2,318.17 msec task-clock # 0.221 CPUs utilized ( +- 0.54% )
876 context-switches # 0.378 K/sec ( +- 4.54% )
0 cpu-migrations # 0.000 K/sec
101,220 page-faults # 0.044 M/sec ( +- 0.01% )
8,046,643,190 cycles # 3.471 GHz ( +- 0.55% )
6,151,488,232 instructions # 0.76 insn per cycle ( +- 0.25% )
1,174,246,810 branches # 506.541 M/sec ( +- 0.24% )
14,519,502 branch-misses # 1.24% of all branches ( +- 0.41% )
10.503 +- 0.928 seconds time elapsed ( +- 8.83% )
Performance counter stats for './sehttpd' (5 runs):
2,931.98 msec task-clock # 0.371 CPUs utilized ( +- 0.36% )
627 context-switches # 0.214 K/sec ( +- 0.86% )
0 cpu-migrations # 0.000 K/sec
1,134 page-faults # 0.387 K/sec ( +- 4.71% )
10,222,300,431 cycles # 3.486 GHz ( +- 0.36% )
9,501,551,090 instructions # 0.93 insn per cycle ( +- 0.03% )
1,792,242,173 branches # 611.274 M/sec ( +- 0.03% )
21,889,467 branch-misses # 1.22% of all branches ( +- 0.71% )
7.90 +- 1.32 seconds time elapsed ( +- 16.74% )
Performance counter stats for './sehttpd' (5 runs):
3,658.49 msec task-clock # 0.406 CPUs utilized ( +- 0.56% )
774 context-switches # 0.212 K/sec ( +- 1.97% )
0 cpu-migrations # 0.000 K/sec
102,289 page-faults # 0.028 M/sec ( +- 0.27% )
12,713,996,125 cycles # 3.475 GHz ( +- 0.40% )
10,128,855,709 instructions # 0.80 insn per cycle ( +- 0.02% )
1,923,276,791 branches # 525.702 M/sec ( +- 0.01% )
25,670,694 branch-misses # 1.33% of all branches ( +- 0.39% )
9.012 +- 0.493 seconds time elapsed ( +- 5.47% )