2016-08-29 51 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提出錯誤報告。

爲什麼改變圖像的大小會產生另一個流?

我的猜測是,有一些性能啓發式的工作,以及是否使用第二個流取決於圖像大小。圖書館是封閉的資源,但是,我不能肯定地說。