Llama писал(а):Victor Gr.,
1) Variable HZ - то грубо говоря частота переключения процессов в системе. При увеличении уменьшается время отклика но растет оверхед на само переключение
Это частота системного таймера, т.е. количество тиков в секунду. Переключение процессов не происходит каждый тик. В общем случае это произойдет если timeslice текущего процесса станет равным 0 (timeslice уменьшается каждый тик).
На данном системном тайемере основана работа "временных"-сервисов ядра. Например, блокировать процесс на заданное количество миллисекунд (что позволяет например работать select() и poll() и т.д.).
Чем больше данная частота, тем в общем случае лучше временное разрешение системы (отклик).
скажем процесс хочет быть пробужден раз в 25 мс., то посмотри какая может быть разница с разрешением таймера в 1 и 10 мс (1000 и 100 HZ соответственно).
с другой стороны, при большей частоте соответствующая часть кода обработки выполняется более часто - оставляя в принципе меньше времени на выполнение процессов и, например, в том числе влияя на состояние кэша и т.д. В том числе, увеличивая энергопотребление например ноутбуков. На сколько я читал, это скорее вопрос нескольких процентов.
В недавнем времени, был опубликован так называемый "dynamic-tick" патч. Идея, грубо говоря, в том что после некоторого времени простоя система перепрограммирует сис. таймер и он производит прерывания с меньшей частотой. Обратное включение может произойти когда что-то переведет систему из состояние бездействия в активное (появилась задача для выполнение). Это либо прерывания, либо какой-то процесс
был блокирован на определенный промежуток времени и этот момент настал. Система "наверстывает" неучтенные тики с помощью спец. обработчика, так как кол-во (известные jiffies) важно для работы.
Желающие могут поискать информацию в интернет, а также проценты спасенного энергопотребления
если требуется более точное разрешение то используется RTC (Real-Time Clock) или подобные.
Llama писал(а):Victor Gr.,
2) Preemptible Kernel - AFAIK это фича которая позволяет динамически понижать приоритет выполнения ядра в пользу некого ресурсоемкого приложения.
нет.
в обшем идею можно проиллюстрировать следующим примером.
процесс блокирован, например в ожидании определенного события.
Он может стать "активным" (TASK_RUNNING) при определенных внешних условиях :
- произошло прерывание и обработчик прерывания "разбудил" данный процесс;
- некоторый в данный момент активный процесс "разбудил" данный процесс;
- процесс был блокирован до определенного момента времени (например он должен делать какую-то работу раз в N милисекунд).
Так вот из-за того или иного события некоторый процесс становится активным. Он готов к выполнению и, допустим, он самый приоритетный процесс в системе. Вот теперь введем понятие "dispatch или scheduling latency" - промежуток времени между тем как некоторый процесс становится активным и моментом когда он действительно начинает выполняться.
Система помечает что есть более приоритетная задача и необходимо провести "вытеснение" текущей в пользу новой.
Если текущий процесс выполняется в user-mode то вытеснение может произойти в данный же момент.
А вот если в kernel-mode то "вытеснение" в данный момент активного процесса в non-preemptible kernel может произойти только в определенных точках:
- если процесс добровольно отдает процессор, блокируясь по той или иной причине;
- если происходит возвращение процесса из kernel mode в user mode.
да отметим, что прерывания прерывают процесс выполняемый в любой точке, если конечно сами прерывания в данный момент разрешены.
В некоторых ядрах добавлялись дополнительный точки "вытеснения".
Идея в том что переключение процессов должно произойти в момент когда ядро находится в целостном состоянии. Исторически, проблема была в том что многие ядра не разрабатывались с учетом возможности выполнения одновременно (несколько активных контекстов в режиме ядра) нескольких процессов в режиме ядра.
так вот положим ядро в некоторой точке может быть либо preemptible либо нет. если да, то процесс выполняемый в данной точке может быть вытеснен в пользу вновь активированного высокоприоритетного.
например общий код ядра завершающий обработку любого прерывания проверяет установку флага (TIF_NEED_RESCHED) - это значит пользовательский обработчик прерывания разбудил некоторый процесс и он оказался приоритетнее текущего - и если ядро в данный момент preemptible то осуществляется переключение контекстов.
Если нет, то в следующей точке где ядро снова станет preemptible - произойдет переключение.
Как пример,
spin_lock(&some_lock); // ядро становится non-preemptible на данном CPU
...
// происходит прерывание и некоторый высокоприоритетный процесс активизирован, но переключение не может произойти сейчас.
...
spin_unlock(&some_lock); // ядро снова становится preemptible (в упрощенном виде, если ничего более не запрещает) . как результат переключение контекстов.
собственно в некоторых точках ядро должно быть невытесняемым, напрмер что произойдет если бы произошло переключение контекстов когда активный процесс обладает spinlock? новый может затребовать этот же spinlock что приведет к deadlock.
отсюда очевидно, чтобы держать отклик системы на высоком уровне, non-preemptible участки ядра должны быть минимальны, как минимум по времени выполнения.
хм... наверное слишком пространно, но надеюсь я был вполне понятен
NUMA?
google в помощь, в общем и по остальным вопросам он бы помог
http://lse.sourceforge.net/numa/faq/ind ... _stand_for