2016-10-21 3 views
0

У меня есть некоторые вопросы, касающиеся регистров памяти CUDAИспользование памяти Регистрация в CUDA

1) Есть ли способ свободных регистров в Cuda ядра? У меня есть переменные, 1D и 2D массивы в регистрах. (максимальный размер массива 48)

2) Если я использую функции устройства, то что произойдет с регистрами, которые я использовал в функции устройства после его выполнения? Будут ли они доступны для вызова выполнения ядра или других функций устройства?

3) Как nvcc оптимизирует использование регистров? Пожалуйста, поделитесь важными моментами, чтобы оптимизировать интенсивное ядро ​​памяти

PS: У меня есть сложный алгоритм для порта в cuda, который занимает много регистров для вычислений, я пытаюсь выяснить, хранить ли промежуточные данные в регистре и написать одно ядро ​​или сохранить его в глобальной памяти и разбить алгоритм в нескольких ядрах.

ответ

2

Только локальные переменные имеют право на проживание в регистрах (см. Также Declaring Variables in a CUDA kernel). У вас нет прямого контроля над тем, какие переменные (скалярный или статический массив) будут находиться в регистрах. Компилятор сделает свой собственный выбор, стремясь к производительности с соблюдением правил хранения.

Использование реестра может быть ограничено с использованием параметров nvcc-компилятора maxrregcount.

Вы также можете разместить большинство небольших массивов 1D, 2D в общей памяти или, если обращаться к постоянным данным, поместите это содержимое в постоянную память (которая кэшируется очень близко к регистру в качестве содержимого кеша L1).

Еще один способ уменьшить использование регистров при работе с вычислимыми связанными ядрами в CUDA - это обрабатывать данные поэтапно, используя несколько глобальных вызовов функций ядра и сохраняя промежуточные результаты в глобальной памяти. Каждое ядро ​​будет использовать гораздо меньше регистров, так что более активные потоки на СМ будут способны скрывать перемещения данных загрузки/хранения. Этот метод в сочетании с правильным использованием потоков и асинхронными передачами данных в большинстве случаев является очень успешным.

Что касается использования функции устройства, я не уверен, но я думаю, что содержимое регистров вызывающей функции будет перемещено/сохранено в локальную память (кэш L1 или так), так же, как разнесение реестра происходит, когда используя слишком много локальных переменных (см. CUDA Programming Guide -> Device Memory Accesses -> Local Memory). Эта операция освободит некоторые регистры для функции вызываемого устройства. После того как функция устройства завершена, их локальные переменные больше не существуют, и регистры могут теперь снова использоваться функцией вызывающего абонента и заполняются ранее сохраненным контентом.

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

+0

Я уже использую общую и постоянную память, но все же из-за интенсивного вычисления алгоритма требуется много регистров (> 255, я действительно задал эти вопросы для вычисления числа регистров, необходимых при разработке алгоритма). Если я храню промежуточные результаты в глобальной памяти и разбиваю вычисления на несколько ядер, то я уверен, что буду тратить много циклов на чтение и запись. Лучше ли выпустить регистры в локальную память? (так что если в графических процессорах следующего поколения будет поддерживаться один и тот же алгоритм, если увеличивается регистр на поток) – Adarsh

+0

@Adarsh: вы не можете вывести количество используемых регистров из исходного кода CUDA, это выбор компилятора, который вы можете ограничить с помощью 'maxrregcount' или используя менее локальные переменные.При переносе кода с CPU на CUDA рассмотрите также возможность изменить свой алгоритм на более удобный для оборудования GPU. Разделение вашей большой задачи на несколько ядер - лучший подход для алгоритмов с привязкой к вычислению (ответ обновлен): менее используемый регистр для ядра, более активные потоки будут скрывать загрузку/сохранение. nvvp сообщит вам, попадает ли ваше ядро ​​в эту категорию. Не будьте уверены, попробуйте. –

+0

@Adarsh, если мой ответ удовлетворил вас, пожалуйста, подпишите его как принятое или уточните, что отсутствует. –

Смежные вопросы