Методы снижения задержки передачи данных с CPU на GPU - PullRequest
13 голосов
/ 28 июня 2011

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

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

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

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

Ответы [ 3 ]

14 голосов
/ 29 июня 2011

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

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

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

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

3 голосов
/ 28 июня 2011

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

0 голосов
/ 18 декабря 2011

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

...