我有一些图像处理代码循环通过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)); } }
循环当前需要~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--; } } }
tvanfosson.. 5
这些都是独立的计算,所以如果你有一个多核CPU,你应该能够通过并行计算获得一些好处.请注意,您需要保留线程,并且只需将它们放在手边即可,因为如果每次重新创建线程,线程创建的开销可能会使速度变慢而不是更快.
可能有用的另一件事是将工作分配给图形处理器.请查看此问题以获取一些想法,例如,使用Accelerator.
这些都是独立的计算,所以如果你有一个多核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--; } } }
编辑:
固定变量无法更改,因此我添加了代码以将指针复制到可以更改的新指针.