Подтвердить что ты не робот

Методы снижения нагрузки процессора на GPU

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

Тем не менее, я немного энтузиаст HPC, и меня заинтересовало направление моих исследований, когда я увидел массовое несоответствие между теоретическим пиком Tianhe-I FLOPS и фактической производительностью LINPACK. Это подняло мою озабоченность по поводу того, нахожу ли я правильный путь карьеры.

Использование памяти с фиксированной памятью (блокировкой страницы) с помощью функции cudaHostAlloc() является одним из способов уменьшения латентности (довольно эффективно), но есть ли какие-либо другие методы, о которых я не знаю? И чтобы быть понятным, я говорю об оптимизации кода, а не о самом оборудовании (что касается работы NVIDIA и AMD).

Как побочный вопрос, я знаю, что Dell и HP продают серверы Tesla. Мне интересно, насколько GPU использует приложение базы данных, где вам потребуется постоянное чтение с жесткого диска (HDD или SSD), операция, которую может выполнять только процессор,

4b9b3361

Ответ 1

Существует несколько способов решения проблем с пропускной способностью CPU-GPU - я надеюсь, что вы подразумеваете под латентностью, а не за латентность самой передачи. Обратите внимание, что я намеренно использовал термин адрес вместо сокращения, так как вам не обязательно уменьшать задержку, если вы можете скрыть его. Также обратите внимание, что я больше знаком с CUDA, поэтому ниже я имею в виду только CUDA, но некоторые функции также доступны в OpenCL.

Как вы уже упоминали блокировка страницы, сама цель увеличения. Кроме того, можно сопоставить память хоста с блокировкой страниц на GPU, механизм, который обеспечивает прямой доступ к данным, выделенным из ядра GPU, без необходимости дополнительной передачи данных. Этот механизм называется переносом с нулевой копией, и это полезно, если данные считываются/записываются только один раз, сопровождаемый значительным количеством вычислений, и для графических процессоров без отдельной памяти (мобильной). Однако, если ядро, обращающееся к нуль-скопированным данным, не сильно связано с вычислением, и поэтому латентность доступа к данным не может быть скрыта, блокировка страницы, но не отображаемая память будет более эффективной. Кроме того, если данные не вписываются в память GPU, нулевая копия все равно будет работать.
Обратите внимание, что чрезмерное количество заблокированных страниц может привести к серьезному замедлению на стороне процессора.

Приближаясь к проблеме под другим углом, как упоминал tkerwin, асинхронная передача (по отношению к потоку процессора, говорящему на GPU) является ключом, чтобы скрыть задержку передачи CPU-GPU путем перекрытия вычислений на CPU с передачей. Это может быть достигнуто с помощью cudaMemcpyAsync(), а также с использованием нулевой копии с асинхронным выполнением ядра.
Это можно сделать еще больше, используя несколько потоков для перекрытия передачи с выполнением ядра. Обратите внимание, что для планирования потока может потребоваться особое внимание для хорошего перекрытия; Карты Tesla и Quadro имеют двухъядерный двигатель DMA, который обеспечивает одновременную передачу данных на GPU и обратно. Кроме того, с CUDA 4.0 стало проще использовать графический процессор из нескольких потоков ЦП, поэтому в многопоточном коде процессора каждый поток может отправлять свои собственные данные на графический процессор и запускать ядра легче.

Наконец, GMAC реализует асимметричную модель общей памяти для CUDA. Одной из его очень интересных особенностей являются модели когерентности, которые она предоставляет, в частности, ленивое и скользящее обновление, позволяющее передавать только данные, модифицированные на CPU заблокированным способом.
Подробнее см. В следующей статье: Gelado et al. - Асимметричная распределенная общая память Модель для гетерогенных параллельных систем.

Ответ 2

Вы можете использовать cudaMemcpyAsync() для дублирования работы, выполняемой на процессоре с передачей памяти. Это не уменьшит задержку передачи данных, но может улучшить общую производительность алгоритма. В нем содержится информация об этом в руководстве CUDA C Best Practices.

Ответ 3

Если латентность является проблемой, возможно, стоит заглянуть в компромисс, который вы можете сделать с архитектурой AMD fusion. Задержка, которую вы получаете, резко минимизирована и может в некоторых случаях быть быстрее, чем передача процессора из ОЗУ. Тем не менее, вы снижаете производительность с использованием недискретного графического процессора.