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慢几十倍上百倍。

 

image

image

image

image

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

 

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

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

 

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

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

一、代码

1. c# TPL

 

 

   1:  private static unsafe Image GrayByParallelForEach(Image image)
   2:  {
   3:      var bmp = (Bitmap) image;
   4:   
   5:      int height = bmp.Height;
   6:      int width = bmp.Width;
   7:   
   8:      var data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
   9:      var startPtr = (PixelColor*)data.Scan0.ToPointer();
  10:      ParallelForEach(startPtr, width, height);
  11:      bmp.UnlockBits(data);
  12:   
  13:      return bmp;
  14:  }
  15:   
  16:  private static unsafe void ParallelForEach(PixelColor* startPtr, int width, int height)
  17:  {
  18:      Parallel.ForEach(Partitioner.Create(0, height), (h) =>
  19:          {
  20:              var ptr = startPtr + h.Item1*width;
  21:   
  22:              for (int y = h.Item1; y < h.Item2; y++)
  23:              {
  24:                  for (int x = 0; x < width; x++)
  25:                  {
  26:                      var c = *ptr;
  27:                      var gray = ((c.Red*38 + c.Green*75 + c.Blue*15) >> 7);
  28:                      (*ptr).Green = (*ptr).Red = (*ptr).Blue = (byte) gray;
  29:   
  30:                      ptr++;
  31:                  }
  32:              }
  33:          });
  34:  }
 
 
   1:      [StructLayout(LayoutKind.Sequential)]
   2:      public struct PixelColor
   3:      {
   4:          public byte Blue;
   5:          public byte Green;
   6:          public byte Red;
   7:          public byte Alpha;
   8:   
   9:      } 

 

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

 

2. c++11 amp 代码

   1: extern "C" __declspec ( dllexport ) void _stdcall gray_image(unsigned int* image, int height,int width)
   2: {
   3:     concurrency::extent<2> image_extent(height, width); 
   4:  
   5:     /* texture of four 8-bit integers */ 
   6:     array_view< unsigned int, 2> image_av(image_extent, image); 
   7:  
   8:     parallel_for_each(image_av.extent,  
   9:         [=](index<2> idx) restrict(amp) 
  10:     { 
  11:         unsigned int color = image_av[idx]; 
  12:         unsigned int a = (color >> 24) & 0xFF; 
  13:         unsigned int r = (color >> 16) & 0xFF; 
  14:         unsigned int g = (color >> 8) & 0xFF; 
  15:         unsigned int b = (color) & 0xFF;
  16:  
  17:         auto gray = ((r * 38 + g * 75 + b * 15) >> 7);
  18:         
  19:         image_av[idx]= a<<24 | gray<<16 | gray<<8 |gray ;     
  20:  
  21:     });
  22:  
  23:     // Copy data from GPU to CPU
  24:     image_av.synchronize();    
  25:  
  26: }

 

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

 

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

 

复制代码
 1     int size= width*height;
 2     PixelColor* ptr= (PixelColor*)image;
 3 
 4     for (int i=0;i<size;i++)
 5     {
 6         auto c = *ptr;
 7         auto gray = ((c.Red*38 + c.Green*75 + c.Blue*15) >> 7);
 8         (*ptr).Green = (*ptr).Red = (*ptr).Blue = (byte) gray;
 9 
10         ptr++;
11     }
复制代码

 

 

二界面

image

 

三源码

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

posted @ 2012-09-01 13:18  董雨  阅读(551)  评论(0编辑  收藏  举报