Mat*_*ren 7 .net c# optimization image-processing
我有一些图像处理代码循环通过2个多维字节数组(相同大小).它从源数组中获取一个值,对其执行计算,然后将结果存储在另一个数组中.
int xSize = ResultImageData.GetLength(0);
int ySize = ResultImageData.GetLength(1);
for (int x = 0; x < xSize; x++)
{
for (int y = 0; y < ySize; y++)
{
ResultImageData[x, y] = (byte)((CurrentImageData[x, y] * AlphaValue) +
(AlphaImageData[x, y] * OneMinusAlphaValue));
}
}
Run Code Online (Sandbox Code Playgroud)
循环当前需要~11ms,我假设主要是因为访问字节数组值,因为计算非常简单(2次乘法和1次加法).
有什么办法可以加快速度吗?它是我的程序的一个时间关键部分,这个代码每秒被调用80-100次,所以任何速度增加,无论多小,都会产生影响.此刻xSize = 768和ySize = 576,但这将在未来增加.
更新:感谢Guffa(请参阅下面的答案),以下代码为每个循环节省了4-5ms.虽然它是不安全的代码.
int size = ResultImageData.Length;
int counter = 0;
unsafe
{
fixed (byte* r = ResultImageData, c = CurrentImageData, a = AlphaImageData)
{
while (size > 0)
{
*(r + counter) = (byte)(*(c + counter) * AlphaValue +
*(a + counter) * OneMinusAlphaValue);
counter++;
size--;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这些都是独立的计算,所以如果你有一个多核CPU,你应该能够通过并行计算获得一些好处.请注意,您需要保留线程,并且只需将它们放在手边即可,因为如果每次重新创建线程,线程创建的开销可能会使速度变慢而不是更快.
可能有用的另一件事是将工作分配给图形处理器.请查看此问题以获取一些想法,例如,使用Accelerator.
要获得此代码的任何实际speadup,您需要使用指针来访问数组,这将删除所有索引计算和边界检查.
int size = ResultImageData.Length;
unsafe
{
fixed(byte* rp = ResultImageData, cp = CurrentImageData, ap = AlphaImageData)
{
byte* r = rp;
byte* c = cp;
byte* a = ap;
while (size > 0)
{
*r = (byte)(*c * AlphaValue + *a * OneMinusAlphaValue);
r++;
c++;
a++;
size--;
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
固定变量无法更改,因此我添加了代码以将指针复制到可以更改的新指针.