Вы можете использовать sudo perf sched record -- ./test
, чтобы определить, какие процессы запланированы для выполнения вместо одного из потоков вашего приложения.Когда я выполняю эту команду в своей системе, я получаю:
sudo perf sched record -- ./test
Launching 4 threads
[ perf record: Woken up 10 times to write data ]
[ perf record: Captured and wrote 23.886 MB perf.data (212100 samples) ]
Обратите внимание, что у меня четыре ядра, а имя исполняемого файла - test
.perf sched
произвел выборку всех событий, связанных с планировщиком, и вывел данные в файл с именем perf.data
по умолчанию.Размер файла составляет около 23 МБ и содержит около 212100 выборочных событий.Продолжительность выборки будет с момента начала perf
до момента окончания test
.
Вы можете использовать sudo perf sched map
для печати всех записанных событий в хорошем формате, который выглядит следующим образом:
*. 448826.757400 secs . => swapper:0
*A0 448826.757461 secs A0 => perf:15875
*. A0 448826.757477 secs
*. . A0 448826.757548 secs
. . *B0 448826.757601 secs B0 => migration/3:22
. . *. 448826.757608 secs
*A0 . . 448826.757625 secs
A0 *C0 . 448826.757775 secs C0 => rcu_sched:7
A0 *. . 448826.757777 secs
*D0 . . 448826.757803 secs D0 => ksoftirqd/0:3
*A0 . . 448826.757807 secs
A0 *E0 . . 448826.757862 secs E0 => kworker/1:3:13786
A0 *F0 . . 448826.757870 secs F0 => kworker/1:0:5886
A0 *G0 . . 448826.757874 secs G0 => hud-service:1609
A0 *. . . 448826.758614 secs
A0 *H0 . . 448826.758714 secs H0 => kworker/u8:2:15585
A0 *. . . 448826.758721 secs
A0 . *I0 . 448826.758740 secs I0 => gnome-terminal-:8878
A0 . I0 *J0 448826.758744 secs J0 => test:15876
A0 . I0 *B0 448826.758749 secs
Двухбуквенные имена A0
, B0
, C0
, E0
и т. Д. Являются короткими именами, присваиваемыми perf
каждому потоку, работающему в системе.Первые четыре столбца показывают, какой поток работал на каждом из четырех ядер.Например, в строке от второй к последней вы можете видеть, что первый поток был создан в вашем цикле for
.Имя, назначенное этой теме: J0
.Поток работает на четвертом ядре.Звездочка указывает, что она только что была переключена на контекст из какого-то другого потока.Без звездочки это означает, что один и тот же поток продолжал работать на том же ядре еще один интервал времени.Точка представляет собой простое ядро.Чтобы определить имена для всех четырех потоков, выполните следующую команду:
sudo perf sched map | grep 'test'
В моей системе это напечатает:
A0 . I0 *J0 448826.758744 secs J0 => test:15876
J0 A0 *K0 . 448826.758868 secs K0 => test:15878
J0 *L0 K0 . 448826.758889 secs L0 => test:15877
J0 L0 K0 *M0 448826.758894 secs M0 => test:15879
Теперь, когда вы знаете двухбуквенные именаназначены на ваши темы (и все другие темы).Вы можете определить, какие другие потоки вызывают переключение контекста в ваших потоках.Например, если вы видите это:
*G1 L0 K0 M0 448826.822555 secs G1 => firefox:2384
, тогда вы будете знать, что три из ваших потоков приложений работают, но одно из ядер используется для запуска Firefox.Поэтому четвертому потоку нужно подождать, пока планировщик не решит, когда планировать снова.
Если вы хотите, чтобы все слоты планировщика занимали хотя бы один из ваших потоков, то вы можете использовать следующую команду:
sudo perf sched map > mydata
grep -E 'J0|K0|L0|M0' mydata > mydata2
wc -l mydata
wc -l mydata2
Последние две команды сообщают вам, сколько строк (временных интервалов) было запущено хотя бы в одном потоке вашего приложения.Вы можете сравнить это с общим количеством временных интервалов.Поскольку имеется четыре ядра, общее количество временных интервалов планировщика равно 4 * (количество временных интервалов).Затем вы можете делать все виды ручных вычислений и точно выяснить, что произошло.