Подтвердить что ты не робот

Как каждый процесс привязан к определенному ядру планировщиком (Linux)

Теперь я изучаю планировщик Linux. Что касается родства ядра процессора, я хотел бы знать следующее:

1) Как каждый процесс (поток) привязан к ядру?

существует системный вызов sched_setaffinity, чтобы изменить сродство ядра, на котором выполняется процесс. Но внутренне, когда генерируется процесс (или поток), как планировщик Linux по умолчанию назначает процесс (поток) конкретному ядру? Я изменил системный вызов sched_setaffinity, чтобы сбрасывать информацию о перемещении задачи из одного ядра в другое.

printk(KERN_INFO "%d %d %ld %lu %s\n", current->pid, current->tgid,
                                       current->state, current->cpus_allowed,
                                       current->comm);

Кажется, что в /var/log/messages нет дампа вышеупомянутой информации. Поэтому планировщик по умолчанию связывает каждый процесс по-другому, но я не могу понять, как это сделать.

2) Можно ли получить идентификатор ядра по PID или другой информации?

Это то, что я хочу реализовать внутри ядра Linux. В task_struct имеется член, называемый cpus_allowed. Но это маска для определения близости, а не идентификатор ядра. Я хочу получить данные, идентифицирующие ядро, на котором запущен указанный процесс.

Спасибо,

4b9b3361

Ответ 1

Каждый процессор имеет свой собственный runqueue, AFAIK, мы можем узнать текущий процессор процесса, посмотрев, к какому runqueue он принадлежит. Учитывая task_struct *p, мы можем получить его runqueue на struct rq = task_rq(p), а struct rq имеет поле с именем cpu, я думаю, это должен быть ответ,

Я не пробовал это на практике, просто прочитал код в Интернете и не совсем уверен, что он будет работать или нет. Пожелайте, чтобы это могло вам помочь.

Ответ 2

Поле 39 в /proc/pid/stat указывает текущее ядро ​​/процессор процесса.

например.:

#cat /proc/6128/stat
6128 (perl) S 3390 6128 3390 34821 6128 4202496 2317 268 0 0 1621 59 0 0 16 0 1 0 6860821 10387456 1946 18446744073709551615 1 1 0 0 0 0 0 128 0 18446744073709551615 0 0 17 8 0 0 0

Процесс 6128 работает на ядре 8.

Ответ 3

Вы можете определить идентификатор ЦП, с которым работает поток, используя его task_struct:

#include <linux/sched.h>

task_struct *p;
int cpu_id = task_cpu(p);

Ответ 4

Идентификация ядра процессора зависит от ОС. ОС знает, как это сделать, вам не нужно. Вы можете столкнуться со всеми проблемами, если вы указали, какое ядро ​​запускается, некоторые из которых могут фактически замедлить процесс.

В ядре Linux структура данных, связанная с процессами task_struct, содержит поле cpu_allowed bitmask. Это содержит n бит по одному для каждого из n процессоров в машине. Машина с четырьмя физическими ядрами имела бы четыре бита. Если бы это ядро ​​процессора было включено с помощью hyperthread, у них была бы восьмибитовая битмаска. Если заданный бит установлен для данного процесса, этот процесс может выполняться на связанном ядре. Поэтому, если процесс разрешен для запуска на любом ядре и разрешен для миграции через процессоры по мере необходимости, битмаска будет полностью равна 1 с. Фактически это состояние по умолчанию для процессов под Linux. Например,

PID  2441: PRIO 0, POLICY N: SCHED_NORMAL, NICE 0, AFFINITY 0x3

процесс 2441 имеет сродство к процессору 0x3, что означает, что он может использоваться в Core0 и Core1.

Приложения также могут указать/установить сродство, используя Kernel API sched_set_affinity(), изменив битмаску.