Как реализовать сходство в многоядерном HT с топологическими соображениями в программе на C ++? - PullRequest
1 голос
/ 18 октября 2011

Я занимаюсь разработкой некоторых многоядерных программ на C ++ с переменным числом потоков, и я хотел бы знать, как установить правильную (на самом деле "лучшую") привязку. Я использую Boost-потоки, поэтому я могу вызвать get_hardware_concurrency (), чтобы узнать, сколько существует логических ядер. До сих пор я писал отображение «n_th thread в n-ое логическое ядро», но это не самая умная вещь из-за многопроцессорных процессоров и HyperThreading. Мои программы всегда похожи на SIMD, поэтому потокам нечего делить между ними, и, в случае компьютера HT, я бы хотел связать потоки с логическими ядрами самым умным способом, который я могу себе представить: первое логическое ядро ​​на первом физическом 1-й логический для 2-го физического, ..., 1-й логический для n-го физического, 2-й логический для 1-го физического и т. Д.

Я нашел много материала, где обсуждается, как узнать, включена ли HT или нет (CPUID), и как определить логические и физические ядра в пакете. Я знаю, что мне приходится иметь дело с некоторым ассемблерным кодом, и это меня не пугает, но я действительно не мог найти, как узнать полную информацию о логических ядрах, физических ядрах и пакетах и ​​как ОС справляется со всем этим.

Будучи наиболее лаконичным, я могу: как узнать точное местоположение (физическое ядро ​​и пакет) потока, который ОС (Windows и Linux) называет N-м?

Ответы [ 4 ]

5 голосов
/ 19 октября 2011

Вот фрагмент кода, который даст вам топологию ЦП в Linux.

#!/bin/bash
function filter {
  cat /proc/cpuinfo | grep -E "$1.*: [0-9]*" | sed -e 's/^.*: //g'
}

CPU_ID=`filter processor`
SOCKET_ID=(`filter 'physical id'`)
CORE_ID=(`filter 'core id'`)

for cpu_id in $CPU_ID; do
    echo "cpu $cpu_id: socket${SOCKET_ID[$cpu_id]}_core${CORE_ID[$cpu_id]}"
done

Если я запусту это на ядре i7 с включенным HT, я получу следующий вывод:

cpu 0: socket0_core0
cpu 1: socket0_core1
cpu 2: socket0_core2
cpu 3: socket0_core3
cpu 4: socket0_core0
cpu 5: socket0_core1
cpu 6: socket0_core2
cpu 7: socket0_core3

Здесь вы можете видеть, что процессоры 0 и 4 находятся на одном ядре, то есть HT-потоки на ядре 0.

Использование этого в сочетании с sched_setaffinity или pthread_setaffinity_np (3) будетпозволит вам сопоставить ваш процесс с набором процессоров.Вы также можете использовать набор задач (1) без строки кода.

3 голосов
/ 18 октября 2011

Для Windows: GetLogicalProcessorInformation и SetThreadAffinityMask

Также есть GetCurrentProcessorNumber(), но ОС часто меняют потоки, когда вы не прикрепляете их кконкретный процессор, так что это само по себе бесполезно.

1 голос
/ 21 мая 2012

вопросов топологии и сходства в многоядерных средах удобно решать с помощью набора инструментов LIKWID. Он содержит, среди прочего, инструменты для определения топологии, закрепления потоков на ядрах и измерения метрик производительности оборудования:

http://code.google.com/p/likwid

Пока механизм потоков в коде основан на pthreads и приложение динамически связано, likwid-pin может связывать потоки с ресурсами без изменения исходного кода.

1 голос
/ 18 октября 2011
...