У меня есть ядро CUDA, обрабатывающее много данных. Поскольку я не могу сразу передать все данные, я должен разбить их на куски и обработать их патронами и обновить выходные данные на графическом процессоре. Я разбираю входные данные из файла. Я думал, могу ли я перекрывать передачи памяти кусков, имея два буфера как на хосте, так и на графическом процессоре. При обработке одного патрона я мог читать другой, передавать его на GPU и запускать ядро в тот же поток. Моя проблема в том, что время выполнения ядра медленнее, чем синтаксический анализ данных и перенос их на 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()
и после чтения и анализа файла вы позволяете ядру также перекрывать эту часть обработки (если ядро работает достаточно долго).
cudaMemcpyAsync
.