Потоки CUDA не работают параллельно

Учитывая этот код:

void foo(cv::gpu::GpuMat const &src, cv::gpu::GpuMat *dst[], cv::Size const dst_size[], size_t numImages)
{
cudaStream_t streams[numImages];
for (size_t image = 0; image < numImages; ++image)
{
cudaStreamCreateWithFlags(&streams[image], cudaStreamNonBlocking);
dim3 Threads(32, 16);
dim3 Blocks((dst_size[image].width + Threads.x - 1)/Threads.x,
(dst_size[image].height + Threads.y - 1)/Threads.y);
myKernel<<<Blocks, Threads, 0, streams[image]>>>(src, dst[image], dst_size[image]);
}
for (size_t image = 0; image < numImages; ++image)
{
cudaStreamSynchronize(streams[image]);
cudaStreamDestroy(streams[image]);
}
}

Глядя на вывод nvvpЯ вижу почти идеальное последовательное выполнение, хотя первый поток — это длительный процесс, с которым другие должны иметь возможность перекрываться.

Обратите внимание, что мое ядро ​​использует 30 регистров, и все они сообщают об «достигнутой занятости» около 0,87. Для самого маленького изображения размер сетки равен [10,15,1], а размер блока [32, 16,1].

0

Решение

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

В вашем случае вы сказали, что запускаете несколько запусков ядра со 150 блоками по 512 потоков в каждом. Ваш GPU имеет 12 SMM (я думаю), и вы могли бы иметь вплоть до 4 блока на SMM, запущенных одновременно (4 * 512 = 2048 потоков, что является пределом SMM). Таким образом, ваш графический процессор может одновременно выполнять максимум 4 * 12 = 48 блоков. При множественном запуске 150 блоков, находящихся в командном конвейере, может показаться, что возможности параллельного выполнения ядра практически нет (возможно, даже нет).

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]