Особенности использования CUDA Zero Copy - PullRequest
10 голосов
/ 15 февраля 2011

Я пытаюсь выяснить, подходит ли использование cudaHostAlloc (или cudaMallocHost?).

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

Могу ли я cudaMallocHost больше места, чем есть на GPU? Если нет, и, скажем, я выделяю 1/4 места, которое мне нужно (которое поместится в GPU), есть ли преимущество в использовании закрепленной памяти?

По сути, мне все равно придется копировать из этого буфера размером 1/4 в мой полноразмерный буфер malloc, и это, вероятно, не быстрее, чем обычное использование cudaMalloc, верно?

Является ли этот типичный сценарий использования правильным для использования cudaMallocHost:

  1. выделить закрепленную память хоста (назовем это «h_p»)
  2. заполнить h_p входными данными-
  3. получить указатель устройства на GPU для h_p
  4. запустить ядро, используя этот указатель устройства для изменения содержимого массива-
  5. используйте h_p как обычно, который теперь изменил содержимое-

Итак, между шагами 4 и 5 не должно быть счастливых копий, верно?

Если это так, то я вижу преимущество для ядер, которые будут одновременно помещаться на GPU, по крайней мере,

Ответы [ 5 ]

6 голосов
/ 18 февраля 2011

Передача памяти является важным фактором, когда речь заходит о производительности приложений CUDA.cudaMallocHost может выполнять две функции:

  • выделять закрепленную память: это хост-память с блокировкой страницы, которую может отслеживать среда выполнения CUDA.Если память хоста, выделенная таким образом, используется в cudaMemcpy в качестве источника или места назначения, среда выполнения CUDA сможет выполнить оптимизированную передачу памяти.
  • выделяет сопоставленную память: это также память с блокировкой страницы, которая можетиспользоваться непосредственно в коде ядра, так как он сопоставлен с адресным пространством CUDA.Для этого вы должны установить флаг cudaDeviceMapHost, используя cudaSetDeviceFlags, прежде чем использовать любую другую функцию CUDA.Размер памяти графического процессора не ограничивает размер отображаемой памяти хоста.

Я не уверен в производительности последнего метода.Это может позволить вам очень хорошо перекрывать вычисления и связь.

Если вы обращаетесь к памяти в блоках внутри вашего ядра (т.е. вам не нужны все данные, а только раздел), вы можете использовать мультибуферизациюметод, использующий асинхронную передачу памяти с помощью cudaMemcpyAsync с использованием нескольких буферов на графическом процессоре: вычисление на одном буфере, передача одного буфера на хост и передача одного буфера на устройство одновременно.

Я полагаю, что ваши утверждения о сценарии использования верны при использовании типа распределения cudaDeviceMapHost.Вам не нужно делать явную копию, но наверняка будет неявная копия, которую вы не увидите.Есть шанс, что это хорошо совпадает с вашими вычислениями.Обратите внимание, что вам может потребоваться синхронизировать вызов ядра, чтобы убедиться, что ядро ​​завершено и что у вас есть измененный контент в h_p.

1 голос
/ 16 февраля 2011

Ни в Руководстве по программированию CUDA C, ни в Руководстве по рекомендациям CUDA не упоминается, что сумма, выделенная cudaMallocHost, может 't быть больше, чем память устройства, поэтому я пришел к выводу, что это возможно.

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

Однако производительность системы (хоста) может сильно пострадать, если количество заблокированных страниц составляетзначительная часть памяти хоста.

Итак, когда использовать эту технику ?, просто: если данные должны быть прочитанными только один раз и записанными только один раз , используйте их.Это приведет к повышению производительности, поскольку в любом случае придется копировать данные туда-сюда.Но как только возникает необходимость сохранять промежуточные результаты, которые не вписываются в регистры или разделяемую память, обрабатывают порции ваших данных, которые помещаются в память устройства, с помощью cudaMalloc.

1 голос
/ 16 февраля 2011

Использование памяти хоста будет на несколько порядков медленнее, чем память на устройстве.Он имеет очень высокую задержку и очень ограниченную пропускную способность.Например, емкость PCIe x16 составляет всего 8 ГБ / с, когда пропускная способность памяти устройства на GTX460 составляет 108 ГБ / с

0 голосов
/ 03 апреля 2012

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

0 голосов
/ 17 февраля 2011
  1. Да, вы можете cudaMallocHost больше места, чем есть в GPU.
  2. Пинованая память может иметь более высокую пропускную способность, но может снизить производительность хоста.Очень легко переключаться между обычной памятью хоста, закрепленной памятью, памятью с комбинированной записью и даже отображенной (без копирования) памятью.Почему бы вам сначала не использовать обычную память хоста и сравнить производительность?
  3. Да, ваш сценарий использования должен работать.

Имейте в виду, что глобальный доступ к памяти устройства медленный, идоступ к памяти узла без копирования еще медленнее.Подходит ли вам нулевое копирование, полностью зависит от того, как вы используете память.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...