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慢几十倍上百倍。
从测试可知,千万像素的时候才差不多持平,
这是我电脑不行咩,还是显卡不行,怎么会这样的结果
准备周一去公司电脑试试,真奇怪
对了,这次测试速度比以前用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++;
}
二界面