На многоядерной машине ОС Linux, когда планировщик процессов будет мигрировать один процесс на другой процессор

В моей программе, чья RSS составляет 65G, при вызове fork, sys_clone->dup_mm->copy_page_range будет потреблять более 2 секунд. В этом случае один процессор будет на 100% sys при выполнении fork, в то же время один поток не сможет получить время процессора до завершения форка. Машина имеет 16 процессоров, остальные процессоры простаивают.

Итак, мой вопрос: один процессор был занят на форке, почему планировщик не переносит процесс, ожидающий на этом процессоре, на другой простаивающий процессор? В общем, когда и как планировщик переносит процесс между процессорами?

Я ищу этот сайт, и существующие темы не могут ответить на мой вопрос.

1 ответ

rss - 65G, когда вызов fork, sys_clone->dup_mm->copy_page_range будет занимать более 2 секунд

Делая fork (или же clone) vmas существующего процесса следует скопировать в vmas нового процесса. dup_mm функция (kernel/fork.c) создает новый mm и сделать актуальную копию. Прямых звонков на copy_page_range, но я думаю, статическая функцияdup_mmap может быть встроен в dup_mm и есть звонки copy_page_range,

в dup_mmap заблокировано несколько замков, оба в новом mm и старый oldmm:

356         down_write(&oldmm->mmap_sem);

После принятия mmap_sem семафор читателя / писателя, существует цикл над всеми mmaps для копирования их метаинформации:

381         for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) 

Только после цикла (это долго в вашем случае), mmap_sem разблокирован:

465 out:
468         up_write(&oldmm->mmap_sem);

В то время как рул mmap_sep писатель не работает, никакой другой читатель или писатель не может ничего сделать с mmaps в oldmm,

один поток не может получить время процессора до завершения форка Итак, мой вопрос: один процессор был занят на форке, почему планировщик не переносит процесс, ожидающий на этом процессоре, на другой процессор простоя?

Вы уверены, что другой поток готов к запуску и не хочет ничего делать с mmaps, например:

  • mmaping что-то новое или unmapping что-то не нужно,
  • растёт или сокращает свою кучу (brk),
  • наращивая свой стек,
  • pagefaulting
  • или много других занятий...?

На самом деле, поток wait-cpu - это мой поток ввода-вывода, который отправляет / получает пакет от клиента, по моим наблюдениям, пакет всегда существует, но поток ввода-вывода не может его получить.

Вы должны проверить стек своего потока ожидания-процессора (даже для этого есть SysRq) и тип ввода / вывода. mmaping of file - вариант ввода / вывода, который будет заблокирован на mmap_sem вилкой

Также вы можете проверить "последний использовавшийся процессор" в потоке wait-cpu, например, в top утилита для мониторинга, включив просмотр потока (H ключ) и добавление столбца "Последний использованный ЦП" к выводу (fj в пожилом возрасте; f выделите P, введите в новее). Я думаю, что возможно, что ваш поток wait-cpu уже был на другом процессоре, просто не разрешен (не готов) к запуску.

Если вы используете форк только для exec, это может быть полезно для:

  • либо переключиться на vfork+exec (или просто чтобы posix_spawn). vfork приостановит ваш процесс (но может не приостановить другие ваши потоки, это опасно), пока новый процесс не сделает exec или же exit, но выполнение может быть быстрее, чем ожидание копирования 65 ГБ mmaps.
  • или не делать форк из многопоточного процесса с несколькими активными потоками и виртуальной памятью объемом несколько ГБ. Вы можете создать небольшой (без использования мульти-ГБ mmaped) вспомогательный процесс, обмениваться данными с ним с помощью ipc, сокетов или каналов и просить его разветвляться и делать все, что вы хотите.
Другие вопросы по тегам