Библиотека сайта rus-linux.net
Что каждый программист должен знать о памяти.
Часть 9: Приложения и библиография
Назад | Оглавление | Вперед |
12.2 Поиск ядер, принадлежащих данному процессору (ядер-братьев)
Если не планируется исполнять два потока на двух гиперпотоках, но от совместного использования кэш-памяти можно получить выигрыш, то нам следует поискать другие ядра процессора. Это трюк выполняется с помощью следующей последовательности кода.
cpu_set_t cur; CPU_ZERO(&cur); CPU_SET(cpunr, &cur); cpu_set_t hyperths; int nhts = NUMA_cpu_level_mask(sizeof(hyperths), &hyperths, sizeof(cur), &cur, 1); cpu_set_t coreths; int ncs = NUMA_cpu_level_mask(sizeof(coreths), &coreths, sizeof(cur), &cur, 2); CPU_XOR(&coreths, &coreths, &hyperths); ncs -= nhts;
Первая часть кода совпадает с кодом для поиска гиперпотоков. Это не случайно, поскольку мы должны отличать гиперпотоки данного процессора от гиперпотоков других ядер. Это реализовано во второй части, где снова вызывается функция NUMA_cpu_level_mask
, но на этот раз с значением уровня равным 2. Все, что остается сделать, это удалить из результата все гиперпотоки данного процессора. Для отслеживания номера битового набора в соответствующих битовых наборов используются переменные nhts
и ncs
.
Результирующая маска может использоваться для планирования еще одного потока. Если явным образом не планируется другой поток, то решение о том, какое использовать ядро, можно возложить на ОС. В противном случае можно в цикле выполнить следующий код:
while (ncs > 0) { size_t idx = 0; while (! CPU_ISSET(idx, &ncs)) ++idx; CPU_ZERO(&cur); CPU_SET(idx, &cur); nhts = NUMA_cpu_level_mask(sizeof(hyperths), &hyperths, sizeof(cur), &cur, 1); CPU_XOR(&coreths, &coreths, hyperths); ncs -= nhts; ... планирование потока для процессора с индексом idx ... }
Цикл на каждой итерации по оставшимся используемым ядрам выбирает номер процессора. Затем для этого процессора вычисляются все гиперпотоки. Затем результирующий битовый набор вычитается (с помощью CPU_XOR
) из битового набора имеющихся ядер. Если с помощью операции XOR не удается что-нибудь удалить, то что-то действительно неправильно. Переменная ncs обновляется, и мы готовы к следующему раунду, но не раньше, чем будут приняты решения о планировании. В конце концов, в зависимости от требований программы можно для планирования потоков использовать любое из значений idx
, cur
или hyperths
. Для ОС часто лучше оставить столько свободы, сколько это будет возможным, и, следовательно, лучше использовать битовый набор hyperths
, с тем, чтобы операционная система сама могла выбирать наилучший гиперпоток.
Назад | Оглавление | Вперед |