Cuda,由NPP功能创建的两个流

时间:2016-08-29 09:10:27

标签: cuda npp

我正在使用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 个答案:

答案 0 :(得分:5)

  

如果我设置[sic]只有一个流,为什么会有两个流?

nppiThreshold_LTValGTVal_32f_C1R似乎创建了自己的内部流来执行它使用的一个内核。另一个是启动到默认流或您使用nppSetStream指定的流。

我认为这确实是文档监督/用户期望问题。 nppSetStream正在按照它所说的做,但没有任何地方声明该库仅限于使用一个流。在文档中可能应该更明确地说明库内部使用了多少个流,以及nppSetStream如何与库交互。如果这对您的应用程序来说是个问题,我建议您使用NVIDIA提交错误报告。

  

为什么更改图像的大小会产生另一个流?

我的猜测是有一些性能启发式工作,以及是否使用第二个流取决于图像大小。图书馆是闭源的,所以我不能肯定地说。