Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

На главную -> MyLDP -> Тематический каталог -> Аппаратное обеспечение

Что каждый программист должен знать о памяти.

Часть 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, с тем, чтобы операционная система сама могла выбирать наилучший гиперпоток.


Назад Оглавление Вперед