ИМЯ
set_mempolicy -
настраивает
политику
работы с
памятью NUMA
для потока
и его
потомков
ОБЗОР
#include <numaif.h>
long set_mempolicy(int mode, const unsigned long *nodemask,
unsigned long maxnode);
Компонуется при указании параметра -lnuma.
ОПИСАНИЕ
Вызов set_mempolicy()
устанавливает
политику
работы с
памятью NUMA
для
вызывающей
нити,
которая
определяется
режимом
политики и
нулём или
более
узлами
(задаются в
аргументах
mode, nodemask и maxnode).
Машина с NUMA
имеет
различные
контроллеры
памяти с
различными
расстояниями
до
определённых
ЦП.
Политикой
памяти
задаётся
узел, на
котором
выделяется
память для
нити.
Этот
системный
вызов
устанавливает
в нити
политику
по
умолчанию.
Политика
нити
управляет
выделением
страниц в
адресном
пространстве
процесса
из
областей
памяти,
которые не
контролируются
специальной
политикой,
заданной с
помощью mbind(2).
Политикой
нити по
умолчанию
также
контролируется
выделение
любых
страниц
для
отображаемых
в память
файлов с
помощью
вызова mmap(2) с
флагом MAP_PRIVATE
(которые
читаются
(загружаются)
только
этой нитью)
и для
отображаемых
в память
файлов с
помощью
вызова mmap(2) с
флагом MAP_SHARED
(независимо
от типа
доступа).
Эта
политика
применяется
только
когда нить
запрашивает
выделение
новой
страницы.
Для
анонимной
памяти это
применяется,
когда
страница
впервые
затрагивается
приложением.
В
аргументе
mode должно
быть
указано
одно из
следующих
значений:
MPOL_DEFAULT, MPOL_BIND, MPOL_INTERLEAVE,
MPOL_PREFERRED или MPOL_LOCAL
(описано
далее). Для
всех
режимов, за
исключением
MPOL_DEFAULT,
требуется,
чтобы
вызывающий
указывал в
аргументе
nodemask узел или
узлы, для
которых
применяется
режим.
Аргумент
mode также
может
содержать
необязательный
флаг
режима.
Поддерживаемые
флаги
режима:
- MPOL_F_STATIC_NODES
(начиная с Linux
2.6.26)
- В
аргументе
nodemask
указываются
идентификаторы
физических
узлов. Linux не
будет
перераспределять
nodemask, если
процесс
перемещается
в другой
контекст
набора
процессоров
или когда
изменяется
набор
узлов,
который
доступен
процессу
согласно
текущему
контексту
набора
процессоров.
- MPOL_F_RELATIVE_NODES
(начиная с Linux
2.6.26)
- В
аргументе
nodemask
указываются
идентификаторы
узлов из
набора
идентификаторов
узлов,
разрешённых
процессу
текущим
контекстом
набора
процессоров.
В nodemask
указывается
битовая
маска
идентификаторов
узлов,
которая
может
содержать
до maxnode бит.
Размер
битовой
маски
округляется
до
следующего
значение
кратного
sizeof(unsigned long), но
ядро будет
использовать
биты
только до
maxnode.
Значение NULL
в nodemask или maxnode
указывает
на пустой
набор
узлов. Если
значение
maxnode равно
нулю, то
аргумент
nodemask
игнорируется.
Если
требуется
аргумент
nodemask, то его
значение
должно
содержать
не менее
одного
работающего
узла,
разрешённого
процессу
из
текущего
контекста
набора
процессоров
(если не
указан
флаг
режима MPOL_F_STATIC_NODES)
и имеющего
память.
Если в mode
установлен
флаг MPOL_F_STATIC_NODES и
требуемое
значение
nodemask не
содержит
узлов,
разрешённых
процессу
из
текущего
контекста
набора
процессоров,
то
политика
памяти
возвращается
обратно к
локальному
выделению.
Это
эффективно
заменяет
указанную
политику
до тех пор,
пока в
текущий
контекст
набора
процессоров
процесса
не
добавится
один или
более
узлов,
указанных
nodemask.
Аргумент
mode должен
включать
одно из
следующих
значений:
- MPOL_DEFAULT
- Данный
режим
устанавливает,
что любые
политики
памяти
нити, не
равные
политике
по
умолчанию,
будут
удалены, и
политика
памяти
«вернётся»
к
системной
политике
по
умолчанию.
Системная
политика
по
умолчанию
— это
«локальное
выделение»,
то есть
выделение
памяти на
узле с ЦП,
на котором
возник
запрос
выделения
Значение
nodemask должно
быть равно
NULL. Если на
«локальном
узле» нет
свободной
памяти, то
система
попытается
выделить
память на
«ближайшем»
узле.
- MPOL_BIND
- Данный
режим
устанавливает
жёсткую
политику,
при
которой
выделение
памяти
выполняется
только на
узлах,
заданных в
nodemask. Если в nodemask
указано
более
одного
узла, то
выделение
страниц
начнётся с
узла с
меньшим
номером
идентификатора
и будет
выполняться
до тех пор,
пока на нём
не
кончится
свободная
память.
Затем
выделение
продолжится
на узле со
следующим
большим
номером
идентификатора,
указанного
в nodemask, и т.д. до
тех пор,
пока на
всех
указанных
узлах не
закончится
свободная
память.
Страницы
не будут
выделяться
на узлах,
не
указанных
в nodemask.
- MPOL_INTERLEAVE
- В этом
режиме
выделение
страниц
чередуется
между
узлами,
указанными
в nodemask,
согласно
порядку
номеров
идентификаторов
узлов. При
этом
происходит
оптимизация
полосы
пропускания,
а не
задержки,
так как
происходит
рассеивание
страниц и
доступ к
этим
страницам
памяти,
разносится
по
нескольким
узлам.
Однако
доступ к
отдельной
странице
по
прежнему
ограничен
шириной
канала с
памятью на
отдельном
узле.
- MPOL_PREFERRED
- В этом
режиме
задаётся
предпочтительный
узел для
выделения
памяти.
Ядро будет
пытаться
сначала
выделить
страницы
на этом
узле и
только
после того
как на
предпочтительном
узле не
хватит
памяти,
попробует
использовать
«ближайшие»
узлы. Если
в nodemask
указано
более
одного
идентификатора
узла, то в
качестве
предпочтительного
будет
использован
первый
узел из
маски. Если
в
аргументах
nodemask и maxnode
указан
пустой
набор, то
политике
предписывается
использовать
«локальное
выделение»
(как при
системной
политике
по
умолчанию,
описанной
ранее).
- MPOL_LOCAL
(начиная с Linux
3.8)
- Этот режим
задаёт
«локальное
выделение»
(local allocation); память,
выделяется
на узле ЦП,
попавшем в
выделение
(«локальный
узел»). В
аргументах
nodemask и maxnode
должен
быть
указан
пустой
набор. Если
на
«локальном
узле» мало
свободной
памяти, то
ядро будет
пытаться
выделить
память на
других
узлах. Ядро
будет
выделять
память на
«локальном
узле»
сразу, как
только на
этом узле
освободится
память.
Если
«локальный
узел» не
разрешён в
текущем
контексте
набора ЦП
процесса,
то ядро
будет
пытаться
выделить
памяти на
других
узлах. Ядро
начнёт
выделять
память на
«локальном
узле»
сразу, как
только это
будет
разрешено
в текущем
контексте
набора ЦП
процесса.
Политика
памяти
нити
сохраняется
при вызове
execve(2) и
наследуется
дочерними
нитями,
созданными
с помощью
fork(2) или clone(2).
ВОЗВРАЩАЕМОЕ
ЗНАЧЕНИЕ
При
успешном
выполнении
set_mempolicy()
возвращается
0; при ошибке
возвращается
-1, а в errno
содержится
код
ошибки.
ОШИБКИ
- EFAULT
- Часть
всего
диапазона
памяти,
заданная в
nodemask и maxnode,
указывает
за пределы
доступного
адресного
пространства.
- EINVAL
- Некорректное
значение
mode. Или
значение
mode равно MPOL_DEFAULT
и значение
nodemask не пусто,
или mode
равно MPOL_BIND
или MPOL_INTERLEAVE и
значение
nodemask пусто.
Или
значение
maxnode больше
чем
количество
значимых
бит
страницы.
Или в nodemask
указан
один или
более
идентификаторов
узлов,
значения
которых
больше чем
максимальный
поддерживаемый
идентификатор
узла. Или
ни один из
идентификаторов
узлов,
указанных
в nodemask, не
работает
или не
разрешены
для
текущего
набора
контекста
процесса,
или ни один
из узлов не
содержит
памяти. Или
в
аргументе
mode указаны
MPOL_F_STATIC_NODES и MPOL_F_RELATIVE_NODES
одновременно.
- ENOMEM
- Недостаточное
количество
памяти
ядра.
ВЕРСИИ
Системный
вызов set_mempolicy()
был
добавлен в
ядро Linux
версии 2.6.7.
СООТВЕТСТВИЕ
СТАНДАРТАМ
Данный
вызов есть
только в Linux.
ЗАМЕЧАНИЯ
Политика
памяти не
запоминается,
если
страница
помещается
в
пространство
подкачки.
Когда
страница
возвращается
в основную
память,
будет
использована
политика
нити или
диапазона
памяти,
действующая
на момент
выделения
страницы.
Информация
о
библиотеке
доступна в
numa(7).