2016-08-29 223 views
1

我正在使用Cuda 7.5和GeForce GTX 650 Ti进行图像处理项目。我决定使用2个数据流,一个应用负责增强图像的算法,另一个应用另一个处理其他处理的独立算法。Cuda,由NPP函数创建的两个流

我写了一个例子来展示我的问题。在这个例子中,我创建了一个流,然后我使用了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的视觉探查了:image_width1344

为什么有两个流,如果我只设置一个流?这会导致我的原始项目中出现错误,所以我正在考虑切换到单个流。

我注意到,这种行为取决于图像的大小,如果srcWidth和srcHeight设置为1500,结果是这样的:image_width1500

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

回答

5

为什么有两个流如果我只设置一个流[原文如此]?

看来,nppiThreshold_LTValGTVal_32f_C1R创建自己的内部流来执行它使用的内核之一。另一个将启动到默认流或您用nppSetStream指定的流中。

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

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

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