【发布时间】:2015-03-22 00:56:31
【问题描述】:
我正在使用 GPU(CUDA)上的图像处理。 CUDA 内核的输入是两个灰度 8 位图像 (.tif)。它们必须在 GPU RAM 内存中作为一维数组(基于 0 的行主要存储)。处理时间约为 24ms,所以阅读速度对我来说很重要。为了做到这一点,首先我需要将图像从 HDD 读取到 CPU RAM 内存(到一维浮点数组),然后使用 cudamemcpy 将其复制到 GPU RAM 中。用c++从硬盘读取最快的方法是什么?
我的图像是 8 位灰度 1200x1600(大小 1.92 mb)。我编写了测试程序,读取大约 250 张图像并测量时间:
使用 matlab (imread) 读取 1 张图像的时间是 5.8ms。这对应于~300 Mb/s,接近我硬盘的峰值带宽。
但是,只要我使用 CUDA,我就需要使用 C++。我安装了OpenCV。不幸的是,我无法使用 OpenCV 将图像直接读入浮点数组。将其读入uchar 数组后,我将数据转换为浮点数组:
image = imread(b, 0);
image.convertTo(img_float, CV_32F);
float *d = img_float.ptr<float>(0);
在测试了这个实现之后,我得到了更糟糕的结果:8.8ms 每张图片。没有转换它是8.2 ms。通常c++ 更快,然后是 Matlab。是否可以像使用 Matlab 一样使用 c++ 实现峰值带宽?
附:在 c++ 中,我使用了 release x64 模式并进行了全面优化。读取 250 张不同图像的时间是通过 c++ 中的函数 clock() 和 matlab 中的 tic-toc 来测量的(除以 250 来计算每张图像的时间)。
谢谢
【问题讨论】:
-
这相当于 ~300 Mb/s,接近我的 HDD 的峰值带宽。 这超过了硬盘驱动器的峰值带宽但对于 SSD 来说是合理的。 SATA 硬盘的最高速度约为 200 MB/s。
-
是的,我有 SSD。我用独立的软件测试对其进行了测试
-
请尝试是否 image = imread(b, -1);更快(无需更改即可加载图像)
-
请注意,clock() 测量 cpu 时间,而 tic-toc 似乎测量墙时间,所以如果 cv::imread 和 .convertTo 是多线程的,那么你在测量中就会给它一个劣势!
-
ok... 测试了
loaded image as is(2nd param = -1) 这没有任何区别。并测试了cv::imread的 wall-time 与 cpu-time,这也没有什么区别。你使用debug或release库吗?