Закрепление процесса на любом процессоре с соблюдением сродства - PullRequest
0 голосов
/ 23 сентября 2018

Допустим, я хочу программно закрепить текущий процесс на одном процессоре, но мне все равно, какой это процессор.

Один простой способ использовать sched_setaffinity с фиксированным номером процессора, возможно0, поскольку всегда должен быть «CPU 0» 1 .

Однако этот подход не работает, если сходство процесса было установлено на подмножество существующих CPU, а невключая тот, который вы выбрали, например, запустив его с taskset.

Так что я хочу выбрать «любой ЦП» для привязки, но только из тех ЦП, которые позволяет текущая маска сродства.Вот один из подходов:

cpu_set_t cpu_set;
if (sched_getaffinity(0, sizeof(cpu_set), &cpu_set)) {
    err("failed while getting existing cpu affinity");
}
for (int cpu = 0; cpu < CPU_SETSIZE; cpu++) {
    if (CPU_ISSET(cpu, &cpu_set)) {
        CPU_ZERO(cpu_set);
        CPU_SET(cpu, &cpu_set);
    }
}
int result = sched_setaffinity(0, sizeof(cpu_set), &cpu_set);

По сути, мы получаем текущую маску сродства, затем перебираем все возможные ЦП в поисках первого допустимого, а затем передаем маску, для которой только этот ЦП установлен на sched_setaffinity.

Однако, если текущая маска соответствия изменилась между get и set вызовами, вызов set завершится неудачно.Есть ли способ обойти это состояние гонки?


1 Хотя нулевой процессор не всегда будет онлайн .

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Учитывая, что маска сходства процесса может измениться в любой момент, вы можете итеративно попытаться закрепить процесс на текущем процессоре и остановить его, если он успешен.

cpu_set_t cpu_set;

int cpu = 0;
int result = -1;

while (result<0){

    cpu = sched_getcpu();
    if (cpu>0){
        CPU_ZERO(&cpu_set);
        CPU_SET(cpu, &cpu_set);
        result = sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
    }
}
0 голосов
/ 01 октября 2018

Вы можете использовать getcpu(), чтобы обнаружить процессор, в котором выполняется ваш процесс, и использовать результат, чтобы установить привязку к этому процессору:

unsigned mycpu=0;
if( -1 == getcpu(&mycpu,NULL,NULL) ) {
   // handle error
}

Предположительно, любой процессор связансуществующие правила будут соблюдаться планировщиком, поэтому вызов getcpu() вернет ЦП, на котором разрешено выполнение процесса.

Существует вероятность того, что набор сходства может измениться, но этокажется очень маловероятным случаем, и разрешенные процессоры могут быть затронуты в какой-то момент в будущем, вне контроля рассматриваемого процесса.

Полагаю, вы могли обнаружить ошибку в вызове sched_setaffinity(),и повторите процесс, пока вызов setaffinity не сработает ...

...