C++ AMP 图像灰度

AMP 学习2 图像灰度,c#比c++ amp快?(转)

http://www.cnblogs.com/xzbrillia/archive/2012/07/22/2603638.html

经过测试几十张图片,得出的结论是,c#用TPL(任务并行库)比 c++ amp方式快 2-10倍

release vs2012 rc

对了,你需要一块dx11的显卡,如果没有,就是软件模拟的大概,速度比gpu慢几十倍上百倍。

 

C++ AMP 图像灰度_第1张图片

C++ AMP 图像灰度_第2张图片

C++ AMP 图像灰度_第3张图片

C++ AMP 图像灰度_第4张图片

从测试可知,千万像素的时候才差不多持平,

 

这是我电脑不行咩,还是显卡不行,怎么会这样的结果

准备周一去公司电脑试试,真奇怪

 

对了,这次测试速度比以前用wpf的要慢,主要差别就是锁定内存的方式不同,

等有空测试一下 wpf下的速度

一、代码

1. c# TPL

private static unsafe Image GrayByParallelForEach(Image image)
{
   var bmp = (Bitmap) image;
 
   int height = bmp.Height;
   int width = bmp.Width;
 
    var data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
    var startPtr = (PixelColor*)data.Scan0.ToPointer();
    ParallelForEach(startPtr, width, height);
    bmp.UnlockBits(data);
 
    return bmp;
}
 
     
private static unsafe void ParallelForEach(PixelColor* startPtr, int width, int height)
{
   Parallel.ForEach(Partitioner.Create(0, height), (h) =>
       {
           var ptr = startPtr + h.Item1*width;
 
     
            for (int y = h.Item1; y < h.Item2; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    var c = *ptr;
                    var gray = ((c.Red*38 + c.Green*75 + c.Blue*15) >> 7);
                    (*ptr).Green = (*ptr).Red = (*ptr).Blue = (byte) gray;
   
                     ptr++;
                 }
           }
       });
}
 
 
   [StructLayout(LayoutKind.Sequential)]
    public struct PixelColor
    {
        public byte Blue;
        public byte Green;
        public byte Red;
        public byte Alpha;
 
    } 


主要是利用微软的 TPL并行库和指针操作,还有一个颜色结构的指针类型转换。

 

2. c++11 amp 代码

extern "C" __declspec ( dllexport ) void _stdcall gray_image(unsigned int* image, int height,int width)
{
    concurrency::extent<2> image_extent(height, width); 
 
    /* texture of four 8-bit integers */ 
    array_view< unsigned int, 2> image_av(image_extent, image); 
 
    parallel_for_each(image_av.extent,  
       [=](index<2> idx) restrict(amp) 
    { 
        unsigned int color = image_av[idx]; 
        unsigned int a = (color >> 24) & 0xFF; 
        unsigned int r = (color >> 16) & 0xFF; 
        unsigned int g = (color >> 8) & 0xFF; 
        unsigned int b = (color) & 0xFF;
  
        auto gray = ((r * 38 + g * 75 + b * 15) >> 7);
         
        image_av[idx]= a<<24 | gray<<16 | gray<<8 |gray ;     
 
     });
  
    // Copy data from GPU to CPU
    image_av.synchronize();    
  
}

貌似 amp中不能使用byte,所以只能通过int来转换。

为了对比,我测试了一下c++普通代码的速度,速度差不多,所以应该不是调用的问题,而是amp本身性能或显卡性能有问题。

int size= width*height;
PixelColor* ptr= (PixelColor*)image;

for (int i=0;i<size;i++)
{
     auto c = *ptr;
     auto gray = ((c.Red*38 + c.Green*75 + c.Blue*15) >> 7);
     (*ptr).Green = (*ptr).Red = (*ptr).Blue = (byte) gray;
      ptr++;
}

 

 

二界面

C++ AMP 图像灰度_第5张图片

 

三源码

http://files.cnblogs.com/xzbrillia/AMP_ImageGray.rar

你可能感兴趣的:(C++ AMP 图像灰度)