Библиотека сайта rus-linux.net
Что каждый программист должен знать о памяти.
Часть 4: Поддержка устройств NUMA
Оригинал: "Memory part 4: NUMA support"Автор: Ulrich Drepper
Дата публикации: October 17, 2007
Перевод: Н.Ромоданов
Дата перевода: апрель 2012 г.
Назад | Оглавление | Вперед |
5.2 Поддержка NUMA в операционной системе
Чтобы операционная система могла поддерживать машины NUMA, она должна принимать во внимание различную природу памяти. Например, если процесс запускается на данном процессоре, то физическая память, назначаемая адресному пространству процесса, должна выбираться из локальной памяти. В противном случае каждая команда должна иметь доступ к удаленной памяти как для кода, так и для данных. Есть особые случаи, присутствующие только в машинах NUMA, которые следует принять во внимание. Текстовый сегмент DSO, как правило, представлен в виде одной копии в физической памяти машины. Но если DSO используется процессами и потоками на всех процессорах (например, базовые библиотеки времени выполнения, такие как libc), то это означает, что у всех, кроме нескольких процессоров, должна быть возможность удаленного доступа. Операционная система в идеале должна "зеркалировать" такие разделяемые DSO в физическую память каждого процессора и использовать локальные копии. Это оптимизация, а не требование, и, в общем случае, трудно реализуемая. Ее либо вообще невозможно реализовать, либо ее можно поддерживать только в ограниченных ситуациях.
Чтобы не ухудшать общую ситуацию, операционная система не должна переносить процесс или поток с одного узла на другой. Операционная система должна пытаться избегать миграции процессов уже даже на обычных многопроцессорных машинах, поскольку переход с одного процессора на другой означает, что будет потеряно содержимое кэш-памяти. Если при перераспределении нагрузки требуется переместить процесс или поток из процессора, то операционная система, как правило, будет выбирать новый процессор произвольным образом, причем такой процессор, у которого достаточно оставшейся мощности. В среде NUMA при выборе нового процессора возникает немного больше ограничений. Затраты на доступ к памяти во вновь выбираемом процессоре не должны превышать аналогичных затрат на старом ранее использовавшемся процессоре, из-за чего происходит ограничение выбора. Если нет свободного процессора, соответствующего указанному критерию, то у операционной системы не остается другого выбора, кроме перехода на процессор, где доступ к памяти стоит дороже.
В такой ситуации есть два возможных выхода. Во-первых, можно надеяться, что ситуация носит временный характер и процесс можно будет перенести обратно на более подходящий процессор. Либо операционная система может перенести память, используемую процессом, на те физические страницы, которые находятся ближе к вновь используемому процессору. Это сравнительно дорогая операция. Возможно, потребуется скопировать огромный объем памяти, хотя и не обязательно за один шаг. Когда это будет происходить, то для того, чтобы старые страницы были перенесены правильно, процесс должен быть остановлен хотя бы и на короткий промежуток времени. Когда происходит перенос страниц памяти, то возникает ряд ограничений, необходимых для того, чтобы обеспечить эффективность и быстрое выполнение операции. В общем, операционная система должна этого избегать в случае, если это действительно не является необходимым.
Обычно нельзя предполагать, что все процессы на машинах NUMA используют один и тот же объем памяти, как также и то, что распределение процессов по процессорам и используемой памяти будет равномерным. На самом деле, если приложения, работающие на машинах, не является очень специализированными (что обычно в мире высокопроизводительных вычислений, но не за его пределами), использование памяти будет весьма неравномерным. Некоторые приложения будут пользоваться большими объемами памяти, другие - вряд ли. Если, в случае, когда возникает запрос, память для процессора выделается локально, то это, рано или поздно приведет к проблемам. В конечном итоге такая система исчерпает память на тех локальных узлах, где процессов работает больше.
Чтобы не возникало таких серьезных проблем, выделение памяти, по умолчанию, не происходит исключительно на локальном узле. Чтобы использовать всю память системы, стратегией, используемой по умолчанию, выбирается разбиение памяти на полосы. Это гарантирует равномерное использование всей памяти, имеющейся в системе. В качестве побочного эффекта, становится возможным свободно перемещать процессы между процессорами, поскольку, в среднем, стоимость доступа ко всей используемой памяти не меняется. Для небольших показателей NUMA, такое выделение полос памяти приемлемо, но оно, все же, не является оптимальным (смотрите данные в разделе 5.4).
Такое решение является пессимистичным; оно поможет системе избежать серьезных проблем и при нормальных условиях эксплуатации сделает ситуацию более предсказуемой. Но такой подход снизит общую производительность системы, причем в некоторых случаях - значительно. Вот почему в системе Linux есть правила распределения памяти, которые можно отдельно выбирать для каждого процесса. Процесс может для себя и порождаемых им процессов выбирать другую стратегию. В разделе 6 мы приведем интерфейсы, которые можно для этого использовать.
Назад | Оглавление | Вперед |