나는 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 이벤트를 가져옵니다.