Re: [閒聊] 來加速一個有趣的東西吧
經過一些修改
速度提升非常多
以我的電腦來說從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)
討論串 (同標題文章)
完整討論串 (本文為第 2 之 2 篇):
C_Sharp 近期熱門文章
PTT數位生活區 即時熱門文章