Краткое изложение : Как можно указать в его коде, что OpenMP должен использовать потоки только для НАСТОЯЩИХ ядер, то есть не считать гиперпотоковые?
Подробный анализ : На протяжении многих лет я кодировал только SW, открытые исходный рендерер (растеризатор / трассировщик лучей) в свободное время. Код GPL и двоичные файлы Windows доступны здесь: https://www.thanassis.space/renderer.html Он компилируется и отлично работает под Windows, Linux, OS / X и BSD.
В прошлом месяце я представил режим трассировки лучей - и качество создаваемых изображений взлетело до небес. К сожалению, трассировка лучей на порядки медленнее, чем растеризация. Для увеличения скорости, как и для растеризаторов, я добавил поддержку OpenMP (и TBB) в трассировщик лучей - чтобы легко использовать дополнительные ядра ЦП. И растеризация, и трассировка лучей легко поддаются распараллеливанию (работа на треугольник - работа на пиксель).
Дома, с моим Core2Duo, второе ядро помогало во всех режимах - и растеризация, и режим трассировки лучей получили ускорение, которое находится между 1.85x и 1.9x.
Проблема: Естественно, мне было любопытно увидеть максимальную производительность процессора (я также «играю» с графическими процессорами, предварительный порт CUDA ), поэтому мне нужна была прочная база для сравнений. Я дал код своему хорошему другу, у которого есть доступ к «звериной» машине с 16-ядерным суперпроцессором Intel за 1500 $.
Он запускает его в «самом тяжелом» режиме, режиме трассировки лучей. ..
... и он получает пятую часть скорости моего Core2Duo (!)
Гасп - ужас. Что только что произошло?
Мы начали пробовать различные модификации, патчи ... и, в конце концов, это выяснили.
Используя переменную среды OMP_NUM_THREADS, можно контролировать количество порождаемых потоков OpenMP. Что только что произошло?
Мы начали пробовать различные модификации, патчи ... и, в конце концов, это выяснили.
Используя переменную среды OMP_NUM_THREADS, можно контролировать количество порождаемых потоков OpenMP. Что только что произошло?
Мы начали пробовать различные модификации, патчи ... и, в конце концов, это выяснили.
Используя переменную среды OMP_NUM_THREADS, можно контролировать количество порождаемых потоков OpenMP. По мере увеличения количества потоков от 1 до 8 скорость увеличивалась (близка к линейному увеличению). В тот момент, когда мы пересекли 8, скорость начала снижаться, пока не упала до одной пятой скорости моего Core2Duo, когда использовались все 16 ядер!
Почему 8?
Потому что 8 было номером реальных ядер. Остальные 8 были ... гиперпоточными!
Теория: Это было новостью для меня - я видел, как гиперпоточность сильно помогает (до 25%) в других алгоритмах, так что это было неожиданно. Очевидно, хотя каждое ядро с гиперпоточностью имеет свои собственные регистры (и модуль SSE?), Трассировщик лучей не может использовать дополнительную вычислительную мощность. Что заставляет меня задуматься ...
Вероятно, не хватает вычислительной мощности - это пропускная способность памяти.
Трассировщик лучей использует структуру данных иерархии ограничивающего объема, чтобы ускорить пересечения лучей и треугольников. Если используются ядра с повышенной резьбой, то каждое из " Я подумал, что это образовательный опыт, и хотел поделиться.