我需要一些帮助来优化一段数学繁重的代码。我已经完成了分析,并隔离了缓慢的方法。问题是每条线路的速度并不慢,但它们被调用了很多很多次,所以我真的需要在这里控制微秒。
此代码用于在执行 NTSC 过滤后转换像素数据。我在各行旁边提供了分析数据作为总运行时间的百分比,因此您可以看到哪些需要工作。此功能总体上占我运行时间的一半左右(48% 自己,53% 带 child )。
// byte[] ntscOutput;
// ushort[] filtered; - the pixels are ushort, because of the texture color depth
int f_i = 0;
int row = 0;
for (int i = 0; i < 269440; i++) // 3.77 %
{
int joined = (ntscOutput[f_i + 1] << 8) + ntscOutput[f_i]; // 6.6 %
f_i += 2; // 1.88 %
filtered[i] = (ushort)joined; // 2.8 %
ushort red = (ushort)(joined & 0xf800); // }
ushort green = (ushort)(joined & 0x7e0); // > 2.36 % each
ushort blue = (ushort)(joined & 0x1f); // }
red = (ushort)((red - (red >> 3)) & 0xf800); // }
green = (ushort)((green - (green >> 3)) & 0x7e0); // > 4.24 % each
blue = (ushort)((blue - (blue >> 3)) & 0x1f); // }
filtered[i + 602] = (ushort)(red | green | blue); // 5.65 %
row++;
if (row > 601)
{
row = 0;
i += 602;
}
}
我愿意接受任何优化方法。如果真的不可能改进实际的数学运算,也许带有不安全代码和指针的东西可以用来操纵数组,以防止这么多的强制转换?也许以某种方式改变我的数组类型,或者某种循环展开?我相信这是可能的,因为过滤操作本身是一个巨大的 C 库函数,包含大量循环和数学运算,整个过程总共占我运行时间的 1.35%。
最佳答案
您要求进行微观优化,但您是否首先尝试过宏观优化?
269440 可以被任何 2^n 整除,这意味着您可以轻松地将此代码线程化到您拥有的处理器数量,并且基本上具有 n 元组的速度。
不过请确保不要在此代码中声明线程。
使用 unchecked 进行微优化关键字可能可以在 rgb block 中实现,方法是用未选中的 {} 包围所有内容,但这可能不会有太大帮助。
真正的优化是:
对于 joined
(ushort) 的所有可能值,将 filtered[i + 602]
的所有结果值存储到一个数组中,每个值都被 (ushort)joined ,并且不使用计算,而是直接从数组中获取值。
然后跳过rgb部分,作为循环体使用:
filtered[i] = (ushort)joined;
filtered[i+602] = precalculatedValues[(ushort)joined];
您可以通过这种方式将 joined 转换为 ushort(在删除按位运算之后)。
关于c# - 帮助优化整数数学,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6406636/