У меня есть ядро CUDA, которое обрабатывает много данных.
Поскольку я не могу передать все данные сразу, мне нужно разделить их на куски, обработать их на куски и обновить вывод на GPU.
Я анализирую входные данные из файла.
Я думал, смогу ли я перекрыть передачу памяти чанками, имея два буфера как в хосте, так и в графическом процессоре. При обработке одного патрона я мог прочитать другой, перенести его в графический процессор и запустить ядро в том же потоке.
Моя проблема в том, что время выполнения ядра медленнее, чем анализ данных и их передача в графический процессор. Как я могу гарантировать, что memcpys не будет записывать поверх данных, которые использует ядро, учитывая тот факт, что memcpys не блокируется?
//e.g. Pseudocode
//for every chunk
//parse data
//cudaMemcpyAsync ( dev, host, size, H2D )
//launch kernel
//switch_buffer
//copy result from device to host
Заранее спасибо.
Просто вставьте явную точку синхронизации с cudaDeviceSynchronize()
после запуска ядра.
Таким образом, вы по сути запускаете передачу памяти и запускаете ядро одновременно. Передача будет идти в один буфер, а ядро будет работать с другим. CudaDeviceSynchronize () будет ждать, пока оба будут выполнены, в это время вы должны поменять местами буферы и повторить.
Конечно, вам также необходимо скопировать результаты с устройства на хост в цикле и добавить логику для обработки первой итерации, когда еще нет данных для обработки ядром, и последней итерации, когда больше нет данных для копия, но все еще один буфер для обработки. Это можно сделать с помощью логики в цикле или путем частичного развертывания цикла, чтобы конкретно кодировать первую и последнюю итерации.
Редактировать:
Перемещая точку синхронизации прямо перед cudaMemcpyAsync()
и после чтения и анализа файла вы позволяете ядру также перекрывать эту часть обработки (если ядро работает достаточно долго).
Других решений пока нет …