#multithreading #performance #rendering #cpu
#многопоточность #Производительность #рендеринг #процессор
Вопрос:
Я всегда боролся с тем, как движки 3D-рендеринга используют процессор. в большинстве ресурсов указано, что чем больше потоков у вас есть, тем выше производительность. давайте подумаем о 4-ядерном и 8-поточном процессоре, если 2 потока используют один и тот же ресурс (ядро) и выполняют одну и ту же работу по рендерингу пикселей, а также процессор работает с полной загрузкой максимальных частот, тогда в чем разница между выполнением всех этих вычислений на одноядерном иоднопоточный? будет ли какое-либо снижение скорости?
Ответ №1:
SMT / hyper-threading обеспечивает небольшое улучшение, но для большинства рабочих нагрузок оно составляет всего одну цифру%. Большая часть выигрыша исходит от 2 вещей:
-
Меньшее переключение контекста при сильно параллельных рабочих нагрузках
-
Более высокая вероятность того, что данные, необходимые хотя бы одному из потоков, будут находиться в кэше процессора. Если в ядре есть только один поток, ядру приходится ждать поступления данных из ОЗУ. Если есть 2 потока, то есть вероятность, что данные для 2-го потока могут находиться в кэше, поэтому ядро может делать что-то продуктивное, пока другие данные поступают из ОЗУ.
Ответ №2:
SMT используется для использования всех EU (исполнительных модулей) ядра.
Если ваш процессор может выполнять два сложения за такт, но ваш код имеет вид:
add r0, r0, r1 #r0 = r0 r1
add r0, r0, r2
add r0, r0, r3
...
тогда вы не сможете сделать лучше, чем одно добавление за такт, поскольку каждая инструкция требует вывода предыдущей.
Это называется цепочкой зависимостей, и в программном обеспечении их обычно много.
Хороший компилятор пишет код, который может использовать больший параллелизм, например, записывая сумму выше как сумму двух подмножеств (которые затем могут выполняться параллельно).
Но написание такого кода сложно и чрезвычайно зависит от конкретной микроархитектуры (читай: модели процессора).
Это был очень простой пример, совместное использование основных ресурсов между двумя потоками имеет свои преимущества, также, если поток останавливается, другой может взять на себя EU, а не оставлять их неиспользованными.
Итак, если вы можете сэкономить «некоторые» транзисторы, почему бы не добавить новый поток выполнения? Это SMT.
Как вы заметили, SMT не подходит для очень хорошо оптимизированного кода. Если все EU могут быть оптимально использованы одним потоком, наличие другого бесполезно.
Но вы не можете сказать (или просто предположить), что программное обеспечение оптимально скомпилировано для вашего процессора, поэтому стоит попробовать использовать SMT.
Кстати, когда люди говорят «чем больше потоков, тем лучше», они обычно имеют в виду «больше EU», для большинства программ это равно «большему количеству потоков» (поскольку большинство программ могут использовать все EUВ потоке), но для небольшого процента это равно «большему количеству ядер».
В общем, сделайте тест.
Случилось так, что мне пришлось написать несколько программ для взлома, я всегда тестирую их, закрепляя несколько экземпляров в потоке на ядро и во всех потоках, и посмотреть, есть ли улучшения.
Когда я использую созданную вручную сборку и библиотеки, их нет.