#c #cuda
#c #cuda
Вопрос:
Я написал программу CUDA, которая уже получает ускорение по сравнению с серийной версией 40 (2600k против GTX 780). Теперь я подумываю об использовании нескольких потоков для параллельного запуска нескольких ядер. Теперь мои вопросы: как я могу измерить свободные ресурсы на моем графическом процессоре (потому что, если у меня нет свободных ресурсов на моем графическом процессоре, использование потоков не имеет смысла, я прав?), И в каком случае использование потоков имеет смысл?
Если меня спросят, я, конечно, могу предоставить свой код, но на данный момент я думаю, что он не нужен для вопроса.
Ответ №1:
Одновременный запуск ядер будет происходить только в том случае, если для этого доступны ресурсы. Один вызов ядра, который «использует» графический процессор, не позволит другим ядрам выполняться значимым образом, как вы уже указали, пока это ядро не завершит выполнение.
Ключевыми ресурсами, о которых следует подумать изначально, являются SMS, регистры, общая память и потоки. Большинство из них также связаны с занятостью, поэтому изучение занятости (как теоретической, т. Е. С помощью калькулятора занятости, так и измеренной) ваших существующих ядер даст вам хорошее общее представление о возможностях получения дополнительной выгоды за счет параллельных ядер.
На мой взгляд, параллельные ядра, вероятно, покажут большую общую выгоду в вашем приложении, только если вы запускаете большое количество очень маленьких ядер, то есть ядер, которые охватывают только один или небольшое количество потоков, и которые очень ограниченно используют разделяемую память, регистры и другие ресурсы.
Лучшим подходом к оптимизации (на мой взгляд) является оптимизация, основанная на анализе. Это позволяет избежать преждевременных или, возможно, ошибочных стратегий оптимизации, таких как «Я слышал о параллельных ядрах, интересно, смогу ли я заставить свой код работать быстрее с ним?» Оптимизация, основанная на анализе, начинается с постановки основных вопросов об использовании, использования профилировщика для ответа на эти вопросы, а затем фокусирования усилий по оптимизации на улучшении показателей, таких как использование памяти или использование вычислений. Параллельные ядра или различные другие методы — вот некоторые из стратегий, которые вы можете использовать для обработки результатов профилирования вашего кода.
Вы можете начать с оптимизации на основе анализа с помощью таких презентаций, как эта.
Ответ №2:
Если вы не указали поток, используется поток 0. Согласно википедии (вы также можете найти ее в структуре cudaDeviceProp), ваш графический процессор GTX 780 имеет 12 потоковых мультипроцессоров, что означает, что при использовании нескольких потоков может быть улучшение. Свойство asyncEngineCount сообщит вам, сколько одновременных асинхронных копий памяти может выполняться.
Идея использования потоков заключается в использовании механизма asyncmemcopy (он же механизм DMA) для перекрытия выполнения ядра и передачи device2host. Количество потоков, которые вы должны использовать для достижения наилучшей производительности, трудно угадать, потому что оно зависит от количества имеющихся у вас DMA-движков, количества SMS и баланса между синхронизациями / количеством параллелизма. Чтобы получить представление, вы можете прочитать эту презентацию (например, слайды 5,6 очень хорошо объясняют идею).
Редактировать: я согласен, что использование профилировщика необходимо в качестве первого шага.