Cuda, два потока, созданные функцией АЭС

Я работаю над проектом обработки изображений с Cuda 7.5 и GeForce GTX 650 Ti. Я решил использовать 2 потока, один, где я применяю алгоритмы, отвечающие за улучшение изображения, и другой поток, где я применяю независимый алгоритм от остальной обработки.

Я написал пример, чтобы показать мою проблему. В этом примере я создал поток, а затем использовал nppSetStream.

Я вызвал функцию nppiThreshold_LTValGTVal_32f_C1R, но при выполнении функции используются 2 потока.

Вот пример кода:

#include <npp.h>
#include <cuda_runtime.h>
#include <cuda_profiler_api.h>

int main(void) {

int srcWidth = 1344;
int srcHeight = 1344;
int paddStride = 0;
float* srcArrayDevice;
float* srcArrayDevice2;
unsigned char* dstArrayDevice;

int status = cudaMalloc((void**)&srcArrayDevice, srcWidth * srcHeight * 4);
status = cudaMalloc((void**)&srcArrayDevice2, srcWidth * srcHeight * 4);
status = cudaMalloc((void**)&dstArrayDevice, srcWidth * srcHeight );

cudaStream_t testStream;
cudaStreamCreateWithFlags(&testStream, cudaStreamNonBlocking);
nppSetStream(testStream);

NppiSize roiSize = { srcWidth,srcHeight };
//status = cudaMemcpyAsync(srcArrayDevice, &srcArrayHost, srcWidth*srcHeight*4, cudaMemcpyHostToDevice, testStream);

int yRect = 100;
int xRect = 60;
float thrL = 50;
float thrH = 1500;
NppiSize sz = { 200, 400 };

for (int i = 0; i < 10; i++) {
    int status3 = nppiThreshold_LTValGTVal_32f_C1R(srcArrayDevice + (srcWidth*yRect + xRect)
        , srcWidth * 4
        , srcArrayDevice2 + (srcWidth*yRect + xRect)
        , srcWidth * 4
        , sz
        , thrL
        , thrL
        , thrH
        , thrH);
}

int length = (srcWidth + paddStride)*srcHeight;
int status6 = nppiScale_32f8u_C1R(srcArrayDevice, srcWidth * 4, dstArrayDevice + paddStride, srcWidth + paddStride, roiSize, 0, 65535);

//int status7 = cudaMemcpyAsync(dstPinPtr, dstTest, length, cudaMemcpyDeviceToHost, testStream);
cudaFree(srcArrayDevice);
cudaFree(srcArrayDevice2);
cudaFree(dstArrayDevice);
cudaStreamDestroy(testStream);
cudaProfilerStop();
return 0;
}

Это то, что я получил от Nvidia Visual Profiler: image_width1344

Почему есть два потока, если я установил только один поток? Это вызывает ошибки в моем исходном проекте, поэтому я думаю переключиться на один поток.

Я заметил, что это поведение зависит от размера изображения, если srcWidth и srcHeight установлены на 1500, результат будет следующим: image_width1500.

Почему изменение размера изображения создает другой поток?

1 ответ

Решение

Почему два потока, если я установил [sic] только один поток?

Похоже, что nppiThreshold_LTValGTVal_32f_C1R создает собственный внутренний поток для выполнения одного из используемых им ядер. Другой запускается либо в поток по умолчанию, либо в поток, который вы указали с помощью nppSetStream,

Я думаю, что это действительно проблема надзора за документацией / ожиданий пользователей. nppSetStream делает то, что говорит, но нигде не сказано, что библиотека ограничена использованием одного потока. Вероятно, в документации должно быть более четко указано, сколько потоков внутри библиотеки использует и как nppSetStream взаимодействует с библиотекой. Если это проблема для вашего приложения, я предлагаю вам сообщить об ошибке в NVIDIA.

Почему изменение размера изображения создает другой поток?

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

Другие вопросы по тегам