作者erspicu (.)
看板C_Sharp
标题Re: [闲聊] 来加速一个有趣的东西吧
时间Sun Mar 17 17:50:54 2013
经过一些修改
速度提升非常多
以我的电脑来说从9秒10秒
提升到1.5秒内
最主要的是卡在FastBitmap里头的mathod还是不够快
所已全部把pixel access地方改用指标存取
速度整个大提升
不过FastBitmap里头其实已经大量改用指标存取了
失败就在get和set pixel时後
动用到C#原生的Color method去包装color物件
public Color GetPixel(int x, int y)
{
pixelData = (PixelData*)(pBase + y * width + x * sizeof(PixelData));
return Color.FromArgb
(pixelData->alpha, pixelData->red, pixelData->green, pixelData->blue);
}
不要怀疑高阶抽像的物件效能就是这麽可怕
大量计算下 一碰到整个low down 连用都不能用
难怪影像.视讯处理领域都还是偏好用C/C++存取pointer来处理
物件导向的东西用在大量计算存取上真的死翘翘
得拆包装 既然得拆包装 很多人乾脆选用别的语言去处理
ok... 1.5秒其实是还可以提升的 瓶颈在於array access
valueRed += ((double)((((FastBitmap.PixelData*)
(index)))->red) * tmpContrib[j]);
^^^^^^^^^^^^^^
是的 就是这个存取的动作耗时 反来不是一些资料类型的转型
或是 + * 的计算
来看看是怎麽回事吧
http://simplygenius.net/Article/FalseSharing
In C#, Is it slower to reference an array variable?
http://stackoverflow.com/questions/5575155/
in-c-is-it-slower-to-reference-an-array-variable
这边已经有点接近计算机组织的问题了 再看看
也许是x86的浮点运算能力不错 倒没有因为浮点计算花太多cost
不过如果是模拟浮点的硬体状况 我看多数会用特殊的方法
把浮点改成用整数来计算(却只损失一点点精确度)
至於回圈 因为会产生竞逐关系 所以也无法用平行处理发挥多核全部效能去处理
要怎麽处里还得想想 如果用到多核 时间大概只需要 0.X了
下面是修改版的部分
static Bitmap HorizontalFiltering(Bitmap bufImage, int iOutW)
{
int dwInW = bufImage.Width;
int dwInH = bufImage.Height;
Bitmap pbOut = new Bitmap(iOutW, dwInH,
PixelFormat.Format24bppRgb);
FastBitmap processor = new FastBitmap(bufImage);
processor.LockImage();
FastBitmap processor_out = new FastBitmap(pbOut);
processor_out.LockImage();
double valueRed = 0.0;
double valueGreen = 0.0;
double valueBlue = 0.0;
byte* index;
FastBitmap.PixelData* data;
for (int x = 0; x < iOutW; x++)
{
int startX;
int start;
int X = (int)(((double)x) * ((double)dwInW) /
((double)iOutW) + 0.5);
int y = 0;
startX = X - nHalfDots;
if (startX < 0)
{
startX = 0;
start = nHalfDots - X;
}
else
{
start = 0;
}
int stop;
int stopX = X + nHalfDots;
if (stopX > (dwInW - 1))
{
stopX = dwInW - 1;
stop = nHalfDots + (dwInW - 1 - X);
}
else
{
stop = nHalfDots * 2;
}
if (start > 0 || stop < nDots - 1)
{
CalTempContrib(start, stop);
for (y = 0; y < dwInH; y++)
{
int i, j;
valueBlue = valueGreen = valueRed = 0;
for (i = startX, j = start; i <= stopX; i++, j++)
{
index =
(processor.pBase + y * processor.width + i * sizeof(FastBitmap.PixelData));
valueRed += ((double)((((FastBitmap.PixelData*)
(index)))->red) * tmpContrib[j]);
valueGreen += ((double)((((FastBitmap.PixelData*)
(index)))->green) * tmpContrib[j]);
valueBlue += ((double)((((FastBitmap.PixelData*)
(index)))->blue) * tmpContrib[j]);
}
if ( valueRed > 255) valueRed = 255;
if ( valueGreen > 255) valueGreen = 255;
if ( valueBlue > 255) valueBlue = 255;
if (valueRed < 0) valueRed = 0;
if (valueGreen < 0) valueGreen = 0;
if (valueBlue < 0) valueBlue = 0;
data = (FastBitmap.PixelData*)(processor_out.pBase +
y * processor_out.width + x * sizeof(FastBitmap.PixelData));
data->red = (byte)( valueRed);
data->green = (byte)( valueGreen);
data->blue = (byte)( valueBlue);
}
}
else
{
for (y = 0; y < dwInH; y++)
{
int i, j;
valueBlue = valueGreen = valueRed = 0;
for (i = startX, j = start; i <= stopX; i++, j++)
{
index = processor.pBase + y * processor.width +
i * sizeof(FastBitmap.PixelData) ;
valueRed += ((double)((((FastBitmap.PixelData*)
(index)))->red) * tmpContrib[j]);
valueGreen += ( (double)
((((FastBitmap.PixelData*)(index)))->green) * tmpContrib[j]);
valueBlue += ((double)
((((FastBitmap.PixelData*)(index)))->blue ) * tmpContrib[j]);
}
if ( valueRed > 255) valueRed = 255;
if ( valueGreen > 255) valueGreen = 255;
if ( valueBlue > 255) valueBlue = 255;
if (valueRed < 0) valueRed = 0;
if (valueGreen < 0) valueGreen = 0;
if (valueBlue < 0) valueBlue = 0;
data = (FastBitmap.PixelData*)
(processor_out.pBase + y * processor_out .width + x *
sizeof(FastBitmap.PixelData));
data->red = (byte) (valueRed);
data->green = (byte)( valueGreen);
data->blue = (byte)( valueBlue);
}
}
}
processor.UnlockImage();
processor_out.UnlockImage();
return pbOut;
}
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.70.79.227
※ 编辑: erspicu 来自: 61.70.79.227 (03/17 17:56)