強力なstrace
は私を失望させました。これはどのようにして可能ですか?
time foo
は、foo
の実行に数秒( "real")かかることを示していますが、ユーザー空間( "user")とカーネル( "sys")の両方で無視できるCPU時間を使用しています。好奇心旺盛な方のために、foo
を以下に定義します。
そのため、CPU命令を実行するのではなく、他の何かを待つのにほとんどの時間を費やしています。通常、私はそれがstrace
でどのように待機しているかを確認できます。つまり、どのシステムコールが長期間ブロックしているのかがわかります。残念ながら、このアプローチは機能しませんでした。
strace -ttt -T -C -w foo
は、システムコール、タイムスタンプ、およびシステムコールに費やされた(実際の)時間の概要を示します。しかし、この特定のプロセスは、システムコールの内部で費やされる全体(実)時間はごくわずかであることを示しました。
foo
は実際にはjournalctl -b -u dev-hugepages.mount
。これを再現するために、最後の引数を毎回別のsystemdユニットに変更する必要があったことを除いて。つまり、調査している遅延は、1つのsystemdユニットのログを初めて取得しようとしたときに発生しました。 [〜#〜] edit [〜#〜]:主な質問に答えた後、私も気づきました この問題が発生した理由遅延の再現 。
このプロセスに費やされる時間は特定の問題であり、明らかにすべてのシステムで発生するわけではありません。 https://github.com/systemd/systemd/issues/796
この問題が発生する通常の理由は、プロセスがページフォールトでブロックしていることです。これらは、メモリマッピング(mmap()
)を通じて実行されるファイルへの読み取りまたは書き込みです。システムコールのトレースでmmap()
に気づいたかもしれません。
time
Shellビルトインの代わりに/usr/bin/time
プログラムを使用していた場合は、次のことに気づいたかもしれません。
0.04user 0.10system 0:02.29elapsed 6%CPU (0avgtext+0avgdata 40464maxresident)k
73632inputs+0outputs (376major+1081minor)pagefaults 0swaps
major
pagefaultsは、ファイルシステムIOを必要とするものです。 minor
ページフォルトはそれほど重要ではありません(おそらく「TLBミス」のみ)。
inputs
は読み取られたページの総数だと思います。現在、ファイルにマップされたページは常に同じサイズだと思います。ほとんどの場合4096バイトですが、getconf PAGESIZE
を確認できます。
したがって、これは290メガバイトに相当し、毎秒100メガバイトを超える速度で読み取ります。これは、私のようなハードディスクの標準速度です。謎解きました!
また、このプロセスには完全に空きCPUがあることを前提としています。そうしないと、他のプロセスがCPUを解放するのを待って、プロセスが単にブロックされる可能性があります。
strace
は、システムコールが原因でプロセスがカーネルに入ったとき(そしてカーネルから出たとき)にのみ表示されます。または、unixシグナルが配信されたとき。ただし、strace
がまったく表示しない他のタイプの割り込みがあります。したがって、これらには