2012-09-24 190 views
1

我想用GPU加速SURF算法。但实际上,我发现CPU(enale TBB)比SURF算法的GPU更快,为 。 我的硬件和操作系统的信息: CPU:英特尔(R)至强(R)CPU E3-1230 V2 @ 3.30GHz(4个核+ 8线程) GPU:Nvidia的GTX 660ti〜1000MHz的(1344个GPU核心) ubuntu的12.04(64bit)为何opencv SURF算法的GPU没有显示CPU的优势?

应用场景: 我的文件夹大约有120张图片。我需要使用SURF为每个图像获取关键点。

时间记录

CPU(TBB)的每张图片,花时间日志:

索引DB:/家庭/ OLE/MatchServer/ImgDB0/IMG 0成本时间SURF ALGO(ON TBB) [S]:0.00666648

索引DB:/家庭/ OLE/MatchServer/ImgDB0/IMG1成本时间onSURF ALGO(ON TBB)[秒]:0.00803925

索引DB:/家庭/ OLE/MatchServer/ImgDB0/SURF ALGO上的img2成本时间(ON TBB)[s]:0.0066344

索引DB:/家庭/ OLE/MatchServer/ImgDB0/IMG3成本时间上SURF ALGO(ON TBB)[秒]:0.00625698

索引DB:/家庭/ OLE/MatchServer/ImgDB0/IMG4成本时间上SURF ALGO(ON TBB)[秒]:0.00699448

索引DB:/家庭/ OLE/MatchServer/ImgDB0/IMG5成本时间上SURF ALGO(ON TBB)[秒]:0.00621663

 .................more.................................. 

GPU为每个图像,花费时间日志(GPU为每个图像有2行日志,一个是上传img到GPU Mem,二是SURF_GPU算法花费时间E):

索引DB:/家庭/ OLE/MatchServer/ImgDB0/IMG 0成本时间对GPU上传图片[S]:1.99329

索引DB:/家庭/ OLE/MatchServer/ImgDB0/IMG 0成本时间在GPU上SURF ALGO [S]:0.00971809

索引DB:/家庭/ OLE/MatchServer/ImgDB0/IMG1成本时间对GPU上传图片[S]:0.000157638

索引DB:/家庭/ OLE/MatchServer/ImgDB0/img1在Gpu上的成本时间SURF ALGO [s]:0.00618778

索引DB:/ home/ole/MatchSer版本/ ImgDB0/IMG2成本时间对GPU上传图片[S]:8.8108e-05

索引DB:/家庭/ OLE/MatchServer/ImgDB0/IMG2成本时间对GPU SURF ALGO [S]:0.00736609

索引DB:/ home/ole/MatchServer/ImgDB0/img3在GPU上载图像的时间[s]:8.8599e-05

索引DB:/ home/ole/MatchServer/ImgDB0/img3 Gpu SURF ALGO [s]:0.00559131

索引DB:/ home/ole/MatchServer/ImgDB0/img4在GPU上传图片的时间:[s]:8。7626e-05

索引DB:/家庭/ OLE/MatchServer/ImgDB0/IMG4成本时间在GPU上SURF ALGO [S]:0.00610033

索引DB:/家庭/ OLE/MatchServer/ImgDB0/IMG5成本时间在GPU上传图片[S]:8.9125e-05

索引DB:在GPU上SURF ALGO [S] /家/ OLE/MatchServer/ImgDB0/IMG5成本时间:0.00632997

 ............................more.................................. 

我发现第一张图像在将图像垫上传到GPU上时的速度非常慢,约为2秒。下一个正常约0.000157638秒。

GPU代码

try 
    { 
     double t0 = (double)getTickCount(); 
     cv::gpu::SURF_GPU surf_gpu; 
     Size size = help_img.size(); 
     Size size0 = size; 
     int type = help_img.type(); 
     cv::gpu::GpuMat d_m(size0, type); 
     if(size0 != help_img.size()) 
      d_m = d_m(Rect((size0.width - size.width)/2, (size0.height - size.height)/2, size.width, size.height)); 
     d_m.upload(help_img); 
     double t = ((double)getTickCount() - t0)/getTickFrequency(); 
     std::cout << "indexing DB:"<< path << " cost time on upload image[s]: " << t << std::endl; 

     t0 = (double)getTickCount(); 
     surf_gpu(d_m, cv::gpu::GpuMat(), help_keypoints); 
     t = ((double)getTickCount() - t0)/getTickFrequency(); 
     std::cout << "indexing DB:"<< path << " cost time on Gpu image[s]: " << t << std::endl; 
    } 
    catch (const cv::Exception& e) 
    { 
     printf("issue happen!"); 
    } 

请帮忙提供有关以下问题的一些建议:

为什么第一次上传图像到GPU,约2秒非常慢?

2.为什么GPU不加速SURF算法,SURF有很多计算,理论上GPU可以加速它。

3.如何做可以提高SURF算法的GPU性能?

谢谢!

回答

3
  1. 第一次上传到GPU将总是比较慢。 GPU在进行一些实际工作之前需要进行初始化。这是因为在第一个CUDA调用中创建了默认的CUDA上下文,在您的情况下,这是上传到GPU Mat。解决方法是在做实际工作之前调用一个随机的GPU函数。

  2. 它取决于您正在比较的GPU和CPU。像使用XEON这样的高端CPU在使用TBB时更有可能获胜。对于实际的加速,请尝试使用NVIDIA Tesla等高端GPU。 OpenCV的当前实现可能没有针对您正在使用的开普勒体系结构GPU进行优化。

  3. 对此没有固定的答案。它取决于算法的并行性质,最优实现以及系统中存在的硬件。

+0

问题1:我得到了答案,谢谢。 Question2:我的显卡是kepler体系结构,所以它有更多的密度核心,我可以理解OpenCV不使用最新的CUDA SDK来支持kepler arch的新功能。但它无法解释比Nvidia老牌Ferim Arch更糟的性能。现在我想用软件模式来解决GPU性能问题。我知道改变硬件Graphic Car是可能的,但是我想尝试它,除非软件无法修复它。问题3:有人可以指导实施吗? – tihuBird