5

Кто-то сказал мне, что графический процессор GeForce GTX 480 может одновременно выполнять 23 000 потоков CUDA. Однако я не совсем понимаю, почему.

Каждое ядро этого графического процессора содержит 2 группы по 16 SIMD-блоков. Каждый блок SIMD имеет 8 ALU и контексты команд. На графическом процессоре 15 ядер.

Следовательно, не должен ли этот графический процессор запускать только 2 * 16 * 8 * 15 = 3840 потоков CUDA одновременно?

1 ответ1

5

Ядра графического процессора могут эффективно запускать много потоков одновременно благодаря тому, что они переключаются между потоками для сокрытия задержки. На самом деле, вам нужно запустить много потоков на ядро, чтобы полностью использовать ваш графический процессор.

Графический процессор глубоко конвейеризован, что означает, что даже если новые инструкции запускаются в каждом цикле, каждая отдельная инструкция может занять много циклов. Иногда инструкция зависит от результата предыдущей инструкции, поэтому она не может начаться (войти в конвейер) до тех пор, пока предыдущая инструкция не завершится (выйти из конвейера). Или это может зависеть от данных из ОЗУ, для доступа к которым потребуется несколько циклов На CPU это может привести к « остановке конвейера » (или "пузырю"), в результате чего часть конвейера будет простаивать в течение нескольких циклов, ожидая начала новой инструкции. Это пустая трата вычислительных ресурсов, но это может быть неизбежно.

В отличие от CPU, ядро GPU может очень быстро переключаться между потоками - порядка одного или двух циклов. Поэтому, когда один поток останавливается на несколько циклов из-за того, что его следующая инструкция еще не может быть запущена, графический процессор может просто переключиться на другой поток и вместо этого запустить свою следующую инструкцию. Если этот поток останавливается, графический процессор снова переключает потоки и так далее. Эти дополнительные потоки выполняют полезную работу на этапах конвейера, которые в противном случае были бы простаивающими во время этих циклов, поэтому, если имеется достаточно потоков, чтобы заполнить пробелы друг друга, графический процессор может выполнять работу на каждом этапе конвейера в каждом цикле. Задержка в одном потоке скрыта другими потоками.

Это тот же принцип, который лежит в основе функции Intel Hyper-Threading, благодаря которой одно ядро выглядит как два логических ядра. В худшем случае потоки, работающие на этих двух ядрах, будут конкурировать друг с другом за аппаратные ресурсы, и каждый из них будет работать с половинной скоростью. Но во многих случаях один поток может использовать ресурсы, которые другой не может использовать - ALU, которые в данный момент не нужны, этапы конвейера, которые будут простаивать из-за остановок, - так что оба потока будут работать с более чем 50% скорости они бы достигли, если бы бегали в одиночку Конструкция графического процессора в основном расширяет это преимущество более чем на два потока.

Возможно, вам будет полезно прочитать руководство NVIDIA CUDA Best Practices, в частности главу 10 ("Оптимизация конфигурации выполнения"), в которой содержится более подробная информация о том, как организовать ваши потоки, чтобы поддерживать работу графического процессора.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .