Cuda,由 NPP 函数创建的两个流
Cuda, two streams created by a NPP function
我正在使用 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.
为什么更改图像的大小会产生另一个流?
Why are there two streams if I setted [sic] only one stream?
似乎 nppiThreshold_LTValGTVal_32f_C1R
创建了自己的内部流来执行它使用的内核之一。另一个启动到默认流,或您使用 nppSetStream
.
指定的流
我认为这确实是一个文档 oversight/user 期望问题。 nppSetStream
按照它说的做,但没有任何地方说图书馆仅限于使用一个流。文档中可能应该更明确地说明库在内部使用了多少流,以及 nppSetStream
如何与库交互。如果这对您的应用程序来说是个问题,我建议您向 NVIDIA 提交错误报告。
Why changing the size of the image produces another stream?
我的猜测是有一些性能试探法在起作用,是否使用第二个流取决于图像大小。但是,该库是闭源的,所以我不能肯定地说。
我正在使用 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.
为什么更改图像的大小会产生另一个流?
Why are there two streams if I setted [sic] only one stream?
似乎 nppiThreshold_LTValGTVal_32f_C1R
创建了自己的内部流来执行它使用的内核之一。另一个启动到默认流,或您使用 nppSetStream
.
我认为这确实是一个文档 oversight/user 期望问题。 nppSetStream
按照它说的做,但没有任何地方说图书馆仅限于使用一个流。文档中可能应该更明确地说明库在内部使用了多少流,以及 nppSetStream
如何与库交互。如果这对您的应用程序来说是个问题,我建议您向 NVIDIA 提交错误报告。
Why changing the size of the image produces another stream?
我的猜测是有一些性能试探法在起作用,是否使用第二个流取决于图像大小。但是,该库是闭源的,所以我不能肯定地说。