私はperfでコンテキスト切り替えイベントを有効にし、perfスクリプトのperf.dataダンプを使用してスレッドのブロック時間を調べようとしました。
これまでに役立つ唯一のロギングオプションは、コンテキスト切り替えとすべてのスケジュールされたイベントです。
これは私がperfで実行するコマンドです。
perf record -g -a -F 999 -e cpu-clock,sched:sched_stat_sleep,sched:sched_switch,sched:sched_process_exit,context-switches
しかし、どちらも不完全に見え、通常 sched_switch イベントは次のようになります。
comm1 0/0 [000] 0.0: 1 sched:sched_switch: prev_comm=comm1 prev_pid=0 prev_prio=0 prev_state=S ==> next_comm=comm2 next_pid=1 next_prio=1
stacktrace...
私の理解によると、prev_commは常にブロックするスレッドであり、next_commはブロック解除するスレッドです。これは正しい仮定ですか?その場合、prev_commで多くのスレッドがブロックされていますが、そのnext_commを取得できないように見えるため、イベントに関する完全なデータを取得できないようです。
コンテキスト切り替えを有効にすることは、スレッドがブロックまたはブロック解除されることに関する情報がないため、多くのことをしないようです(完全に欠けている部分がなければどのように機能するかを説明したいと思います)。
一般的なコンテキスト切り替えイベントは次のとおりです。
comm1 0/0 [000] 0.0: 1 context-switch:
stacktrace...
tl;dr、パフォーマンススクリプトの出力でLinuxのブロック時間調査をどのように実行し、パフォーマンスロギングでどのオプションを有効にする必要がありますか?
ありがとうございます。
答え1
この質問は古いですが(2月16日)、他の人に役立つように答えます。問題は「-F 999」と入力したことです。これは、毎秒999回の頻度でイベントをサンプリングすることを意味します。 「追跡」イベントの場合、通常はサンプリングしたくありません。たとえば、sched:sched_switchを選択した場合は、すべてのコンテキスト遷移を表示したいと思います。 -F 999 と入力すると、コンテキスト切り替えサンプルを取得できます。以下を使って「perf Record」cmdの出力を見ると:
perf script --verbose -I --header -i perf.dat -F comm,pid,tid,cpu,time,period,event,trace,ip,sym,dso > perf.txt
これにより、「ピリオド」(タイムスタンプとイベント名の間の数字)が(通常)== 1ではないことがわかります。
以下のように「perf Record」cmdを使用すると、次のように「perf script」出力にサイクル1が表示されます。
Binder:695_5 695/2077 [000] 16231.700440: 1 sched:sched_switch: prev_comm=Binder:695_5 prev_pid=2077 prev_prio=120 prev_state=S ==> next_comm=kworker/u16:17 next_pid=7665 next_prio=120
説明は長いですが、基本的にはしないでください(ここで「that」は「-F 999」です)。
次のようにすれば:
perf record -a -g -e sched:sched_switch -e sched:sched_blocked_reason -e sched:sched_stat_sleep -e sched:sched_stat_wait sleep 5
これにより、出力に各コンテキストスイッチと各イベントの呼び出しスタックが表示されます。以下を行う必要があります。
echo 1 > /proc/sys/kernel/sched_schedstats
sched_stat イベントを取得します。