Копирование целого числа из GPU в CPU - PullRequest
5 голосов
/ 15 марта 2011

Мне нужно копировать одно логическое или целочисленное значение с устройства на хост после каждого вызова ядра (я вызываю одно и то же ядро ​​в цикле for). То есть после каждого вызова ядра мне нужно отправлять целое число или логическое значение обратно на хост. Каков наилучший способ сделать это?

Должен ли я записать значение непосредственно в ОЗУ? Или я должен использовать cudaMemcpy ()? Или есть другой способ сделать это? Будет ли копирование только 1 целого числа после каждого запуска ядра замедлять мою программу?

Ответы [ 4 ]

4 голосов
/ 15 марта 2011

Позвольте мне сначала ответить на ваш последний вопрос:

Будет ли копирование всего 1 целого числа после каждого запуска ядра замедлять мою программу?

Немного - да.Выполнение команды, ожидание ответа графического процессора и т. Д., И т. Д. Количество данных (1 int против 100 ints), вероятно, не имеет большого значения в этом случае.Тем не менее, вы все равно можете достичь скорости тысяч передач памяти в секунду.Скорее всего, ваше ядро ​​будет работать медленнее, чем эта единичная передача памяти (в противном случае, вероятно, лучше будет выполнить всю задачу на процессоре)

Каков наилучший способ сделать это?

Ну, я бы предложил просто попробовать это самостоятельно.Как вы сказали: вы можете использовать закрепленную на карте память и сделать так, чтобы ваше ядро ​​сохраняло значение непосредственно в ОЗУ, или использовать cudaMemcpy.Первый из них может быть лучше, если ваши ядра все еще имеют некоторую работу после отправки целого числа обратно.В этом случае задержка отправки его на хост может быть скрыта при выполнении ядра.

Если вы используете первый метод, вам придется вызвать cudaThreadsynchronize(), чтобы убедиться, что ядро ​​завершило свое выполнение.,Вызовы ядра являются асинхронными.

Вы можете использовать cudaMemcpyAsync, который также является асинхронным, но в GPU не может быть запущено ядро, а cudaMemcpyAsync выполняется параллельно, если вы не используете потоки.

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

1 голос
/ 16 марта 2011

Почему бы не использовать закрепленную память?Если ваша система поддерживает это - см. Раздел Руководства по программированию CUDA C о закрепленной памяти.

0 голосов
/ 16 марта 2011

Если вам нужно, чтобы значение, вычисленное в предыдущем обращении к ядру, запустило следующий, то сериализуется, и вы выбираете cudaMemcpy (dst, src, size = 1, ...);

Если все параметры запуска ядра не зависят от предыдущего запуска, вы можете сохранить все результаты каждого вызова ядра в памяти GPU, а затем загрузить все результаты сразу.

0 голосов
/ 15 марта 2011

Копирование данных в и из GPU будет намного медленнее, чем доступ к данным из CPU. Если вы не используете значительное количество потоков для этого значения, это приведет к очень низкой производительности, не делайте этого.

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

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