私の基本的な仮定は、プロセスの唯一の制限要因がディスクとCPUである場合、システムの「iowait」とCPUの合計使用量は、1つの論理CPUの少なくとも100%に等しくなることです。(他の場合、これは保持されません。たとえば、を使用してファイルをダウンロードする場合wget、ネットワークが制限要因になることがよくあります)。
この仮定は単純なテストに違反しています。これは予想されますか?それが期待されている場合は、私は一連の条件が存在しなければならない私の仮定が成り立つことを期待しますか?
ここに「iowait」についての背景があります:CPUはIO保留があることをどのように知るのですか? ここでの答えは、累積iowaitが「特定の条件で減少する可能性がある」という直感に反するアイデアを引用しています。私の簡単なテストがそのような文書化されていない状態を引き起こしているのではないかと思いますか?
更新:答えにスキップしてください。
答えには、最初に使用したものよりも簡単なテストがあります。以下の元の質問を保存しました。元の質問に追加の詳細が表示される場合があります。
元の質問
短いテストではdd、カーネルにランダムバイトの生成を要求し、それらをファイルに書き込むために使用します。カーネル内で費やされたCPU時間のカウントを取得するためだけに、ddコマンドを実行しperf statます。内部perf trace -sで費やした時間を報告するために内部で実行しwrite()ます。同時に、vmstat 5別のターミナルで実行して、システム「iowait」を確認します。
- 少なくとも1つのCPU全体が「非アイドル」、つまり、100%の時間、実行中または停止しているがIOを待機している(「iowait」状態)として表示されると予想していました。そうではありませんでした。
- (また、「iowait」の時間は、write()で費やされた時間とほぼ一致することを期待していました。しかし、そうではなかったようです。)
詳細な結果とテスト環境を以下に示します。また、別のテストも示していますが、ここでは私の仮定が当てはまりました。注:perf statinside を実行する必要がありましたがperf trace、その逆ではありません。詳細については、「perf trace-s」を実行すると、「perf stat」(および「time」!)に誤った結果が表示されますか?
「iowait」に関する背景情報
以下は、
sarマンページから取られた定義です。%iowait:
1つまたは複数のCPUがアイドル状態であった間に、システムに未処理のディスクI / O要求があった時間の割合。
したがって、%iowaitは、CPUの観点からは、実行可能なタスクはないが、少なくとも1つのI / Oが進行中であったことを意味します。iowaitは、何もスケジュールできないアイドル時間の単なる形式です。この値は、パフォーマンスの問題を示すのに役立つ場合もあれば、そうでない場合もありますが、システムがアイドル状態であり、さらに作業が必要な可能性があることをユーザーに伝えます。
https://support.hpe.com/hpsc/doc/public/display?docId=c02783994
また、より長い記事:I / O待機について(または0%のアイドルがOKになる理由)もあります。これは、カーネルコードから定義を明確に見る方法を説明しています。コードは多少変更されていますが、アイデアはまだ明確です。
/*
* Account for idle time.
* @cputime: the CPU time spent in idle wait
*/
void account_idle_time(u64 cputime)
{
u64 *cpustat = kcpustat_this_cpu->cpustat;
struct rq *rq = this_rq();
if (atomic_read(&rq->nr_iowait) > 0)
cpustat[CPUTIME_IOWAIT] += cputime;
else
cpustat[CPUTIME_IDLE] += cputime;
}
また、この記事では、シングルCPUシステムに関する多数の関連する実験も示しています。実験の一部としても使用ddしてif=/dev/urandom !しかし、実験には私のテストは含まれていませんdd if=/dev/urandom of=test.out 。のみを使用しdd if=/dev/urandom of=/dev/null ます。
「IO待機」は、マルチCPUシステムを使用しているため、今は少し注意が必要ですが、引用符で囲まれたコードに基づいて理解できていると思います。
環境
4つの論理CPUがあります。
私はLVMとext4ファイルシステムを使用します。ディスクまたはファイルシステムで暗号化を使用していません。ネットワークファイルシステムがまったくマウントされていないため、ネットワークファイルシステムの読み取りまたは書き込みを行っていません。
以下の結果は4.20.15-200.fc29.x86_64、noopIOスケジューラを使用したkernelからのものです。cfqIOスケジューラも同様の結果が得られます。
(同様の構成に基づいたカーネルビルドでも同様の結果が見られましたが、カーネルバージョン5.1に近く、使用していましたmq-deadline。そのため、新しいblk-mqコードを使用していました)。
テストと結果
$ sudo perf trace -s \
perf stat \
dd if=/dev/urandom of=test.out bs=1M oflag=direct count=3000
3000+0 records in
3000+0 records out
3145728000 bytes (3.1 GB, 2.9 GiB) copied, 31.397 s, 100 MB/s
Performance counter stats for 'dd if=/dev/urandom of=test.out bs=1M oflag=direct count=3000':
18,014.26 msec task-clock # 0.574 CPUs utilized
3,199 context-switches # 0.178 K/sec
4 cpu-migrations # 0.000 K/sec
328 page-faults # 0.018 K/sec
45,232,163,658 cycles # 2.511 GHz
74,538,278,379 instructions # 1.65 insn per cycle
4,372,725,344 branches # 242.737 M/sec
4,650,429 branch-misses # 0.11% of all branches
31.398466725 seconds time elapsed
0.006966000 seconds user
17.910332000 seconds sys
Summary of events:
...
dd (4620), 12156 events, 12.0%
syscall calls total min avg max stddev
(msec) (msec) (msec) (msec) (%)
--------------- -------- --------- --------- --------- --------- ------
read 3007 17624.985 0.002 5.861 12.345 0.21%
write 3003 13722.837 0.004 4.570 179.928 2.63%
openat 12 0.371 0.002 0.031 0.267 70.36%
...
iowaitのwaコラムから図を読みましたvmstat。io列(bo= 1Kブロックの出力)を見ることで、テストが実行されていることを確認できます。
$ vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 5126892 176512 1486060 0 0 1788 4072 321 414 4 4 83 9 0
1 0 0 5126632 176520 1485988 0 0 0 7 212 405 0 1 99 0 0
0 0 0 5126884 176520 1485988 0 0 0 0 130 283 0 0 99 0 0
0 0 0 5126948 176520 1485908 0 0 0 1 157 325 0 0 99 0 0
0 0 0 5126412 176520 1486412 0 0 115 0 141 284 0 0 99 0 0
0 2 0 5115724 176548 1487056 0 0 0 6019 18737 10733 3 6 89 2 0
1 0 0 5115708 176580 1487104 0 0 3 91840 1276 990 0 13 77 9 0
1 0 0 5115204 176600 1487128 0 0 2 91382 1382 1014 0 14 81 4 0
1 0 0 5115268 176636 1487084 0 0 4 88281 1257 901 0 14 83 3 0
0 1 0 5113504 177028 1487764 0 0 77 92596 1374 1111 0 15 83 2 0
1 0 0 5114008 177036 1487768 0 0 0 113282 1460 1060 0 16 81 2 0
1 0 0 5113472 177044 1487792 0 0 0 110821 1489 1118 0 16 74 10 0
0 0 0 5123852 177068 1487896 0 0 0 20537 631 714 1 3 94 2 0
0 0 0 5123852 177076 1487856 0 0 0 10 324 529 2 1 98 0 0
2 0 0 5123852 177084 1487872 0 0 0 70 150 299 0 0 99 0 0
保持されるテスト結果(VM内)
1 CPUのVM内で同じテストを試みましたが、これはカーネル5.0.9-301.fc30.x86_64を実行していてmq-deadline(したがってblk-mq)を使用していました。このテストでは、期待どおりに機能しました。
$ sudo perf trace -s \
perf stat \
dd if=/dev/urandom of=test.out bs=1M oflag=direct count=3000
[sudo] password for alan-sysop:
3000+0 records in
3000+0 records out
3145728000 bytes (3.1 GB, 2.9 GiB) copied, 46.8071 s, 67.2 MB/s
Performance counter stats for 'dd if=/dev/urandom of=test.out bs=1M oflag=direct count=3000':
18,734.89 msec task-clock # 0.400 CPUs utilized
16,690 context-switches # 0.891 K/sec
0 cpu-migrations # 0.000 K/sec
328 page-faults # 0.018 K/sec
<not supported> cycles
<not supported> instructions
<not supported> branches
<not supported> branch-misses
46.820355993 seconds time elapsed
0.011840000 seconds user
18.531449000 seconds sys
Summary of events:
...
dd (1492), 12156 events, 38.4%
syscall calls total min avg max stddev
(msec) (msec) (msec) (msec) (%)
--------------- -------- --------- --------- --------- --------- ------
write 3003 28269.070 0.019 9.414 5764.657 22.39%
read 3007 18371.469 0.013 6.110 14.848 0.53%
execve 6 10.399 0.012 1.733 10.328 99.18%
...
の出力vmstat 5:
$ vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 726176 52128 498508 0 0 2040 231 236 731 7 5 77 11 0
0 0 0 726176 52136 498508 0 0 0 10 25 46 0 0 99 1 0
0 0 0 726208 52136 498508 0 0 0 0 29 56 0 0 100 0 0
0 1 0 702280 55944 511780 0 0 2260 13109 4399 9049 3 17 55 25 0
0 1 0 701776 56040 511960 0 0 18 129582 1406 1458 0 73 0 27 0
0 2 0 701524 56156 512168 0 0 22 87060 960 991 0 50 0 50 0
3 1 0 701524 56228 512328 0 0 14 118170 1301 1322 0 68 0 32 0
1 1 0 701272 56260 512392 0 0 6 86426 994 982 0 53 0 46 0
0 2 0 701020 56292 512456 0 0 6 56115 683 660 0 37 0 63 0
3 2 0 700540 56316 512504 0 0 5 33450 446 457 0 26 0 74 0
0 2 0 700860 56332 512536 0 0 3 16998 311 240 0 19 0 81 0
1 2 0 700668 56368 512616 0 0 7 32563 443 428 0 24 0 76 0
1 0 0 700668 56392 512648 0 0 3 20338 245 272 0 12 0 88 0
0 1 0 707096 56408 512920 0 0 54 20913 312 530 0 12 79 8 0
0 0 0 707064 56432 512920 0 0 0 49 39 64 0 0 45 55 0
0 0 0 707064 56432 512920 0 0 0 0 24 46 0 0 100 0 0
0 0 0 707064 56432 512920 0 0 0 80 28 47 0 0 100 0 0
CPUをVMにホットアドして、もう一度テストしてみました。結果はさまざまでした。アイドル列に約0%が表示されることもあれば、約50%のアイドルが表示されることもありました(2つのCPUのうち1つ)。0%の「アイドル」の場合、「iowait」は非常に高く、複数のCPUに相当します。すなわち、私の期待ポイント2は正しくありませんでした。マルチCPUシステムでの「iowait」のこの明らかな制限を、しぶしぶ受け入れることができます。(私はそれをよく理解していませんが、誰かがそれを正確に説明したいなら、それは素晴らしいでしょう)。ただし、どちらの場合も「アイドル」は50%を超えていなかったため、これらのテストは「iowait」に関する最初の仮定と一致していました。
VMをシャットダウンして、4つのCPUで起動しようとしました。同様に、多くの場合、アイドル状態は正確に75%であり、50%程度のアイドル状態であったこともありましたが、75%以上のアイドル状態はありませんでした(4つのCPUのうち3つ以上)。
一方、4つのCPUを備えた物理システムでは、上記のように80%以上のアイドル状態の結果を再現できます。
this_rq()->nr_iowaitはio_schedule() 、現在のCPUのみで使用を待機しているタスクの数だと思います。私が間違っている?
iowait一般にI / Oの待機時間を測定しようとしています。特定のCPUによって追跡されず、追跡することもできません」と答えていることと一致しています。私はこれを確信していませんが、ただ驚きを表明しています。
atop、またはatopsar -c 5、CPUごとの使用量の数値が表示されます。それらにはiowaitが含まれ、CPUごとのiowaitの数値は異なるゼロ以外の値を表示できます:-)。またはsar -P ALL 1、使用しない場合atop。これは、iowaitモデルがマルチCPUシステム用に拡張された方法です...このモデルが実際に使用できるかどうか、またはCPUが1つしかないときにiowaitコードが動作し続けることができるかどうかは不明ですオンラインですが、それ以外の場合は信頼できません。