Jetson TK1上的OpenCV比定制Cuda代码慢得多

Jetson TK1上的OpenCV比定制Cuda代码慢得多,opencv,cuda,Opencv,Cuda,我正在Jetson TK1上开发一个OpenCV应用程序。我使用的是NVIDIA提供的OpenCV4Tegra软件包 dpkg-l输出: ii libopencv4tegra 2.4.10.1 armhf OpenCV4Tegra ii libopencv4tegra-dev

我正在Jetson TK1上开发一个OpenCV应用程序。我使用的是NVIDIA提供的OpenCV4Tegra软件包

dpkg-l输出:

ii  libopencv4tegra                                       2.4.10.1                                            armhf        OpenCV4Tegra
ii  libopencv4tegra-dev                                   2.4.10.1                                            armhf        OpenCV4Tegra
ii  libopencv4tegra-repo                                  2.4.10.1                                            armhf        OpenCV4Tegra
我想知道Jetson能为我的申请提供多大的加速

我已经测试过将数据从主机复制到设备

OpenCV代码:

cv::Mat src_host = cv::imread("image.png");
cv::gpu::GpuMat src;
src.upload(src_host);
我已将上载调用放入循环并计时。它通常平均为10毫秒左右

当我尝试类似的Cuda代码时:

cv::Mat src_host = cv::imread("image.png");
int nb_bytes = src_host.rows*src_host.cols*src_host.elemSize1();
uchar* data;
cudaMalloc(&data, nb_bytes);
cudaMemcpy(data, src_host.data, nb_bytes, cudaMemcpyHostToDevice);
此代码的平均值约为50-100us

当我尝试OpenCV操作时,例如:

cv::gpu::GaussianBlur(src, dst, cv::Size(25, 25), 0);
这也需要比定制Cuda实现长一个数量级的时间


我是否错误地使用了OpenCV的gpu功能?我是否做出了错误的假设?

如果您使用nvvp启动代码,您将看到opencv在您可以在设备上执行的每个操作后调用cudaDeviceSynchronize

为了避免这些同步,您必须通过创建gpu::Stream来使用它们的异步API,并在流中启动您的操作

不要忘记在所有内核调用之后放置一个synchronize


您还可以注意到,对于某些操作(腐蚀/扩张/高斯模糊/…),第一次调用的时间比其他调用长,为了避免在设备初始化期间调用它们一次,以便在初始化之后正确地对代码进行基准测试。

如果使用nvvp启动代码,您将看到在设备上执行的每个操作之后,opencv调用cudaDeviceSynchronize

为了避免这些同步,您必须通过创建gpu::Stream来使用它们的异步API,并在流中启动您的操作

不要忘记在所有内核调用之后放置一个synchronize

您还可以注意到,对于某些操作(腐蚀/扩张/高斯模糊/…),第一次调用的时间比其他调用的时间长,以避免在设备初始化期间调用它们一次,以便在之后正确地对代码进行基准测试