在c#中存储2D数组以便在对数组中的元素执行大量算术时优化性能的最佳方法是什么?
我们有大的(大约1.5G)数组,例如我们想要逐个元素地相乘。表现至关重要。完成此操作的上下文是在c#中。有没有智能的方法来存储数组并迭代它们?我们可以用非托管C ++编写这些部分吗?这会真的提高性能吗?数组需要可以访问c#程序的其余部分。
目前(在c中)数组存储为单个长向量。我们对数组中的每个元素执行计算并覆盖旧值。对于向量中的每个元素,计算通常是唯一的。
时序实验表明,在C#中作为数组存储和迭代数据比将其存储为2D数组要慢。我想知道是否有更好的方法来处理数据。所进行的特定算术与该问题无关。
答案 0 :(得分:8)
安娜,
这是一个很好的页面,讨论传统科学编程语言(fortran,C ++)和c#之间的性能差异。
http://msdn.microsoft.com/en-us/magazine/cc163995.aspx
根据文章C#,当使用矩形阵列(2d)时可以是非常好的表演者。下面的图表显示了锯齿状数组(数组数组)和矩形数组(多维)数组之间的性能差异。
alt text http://i.msdn.microsoft.com/cc163995.fig08.gif
我建议您自己进行试验,并使用VS 2008中的性能分析进行比较。
如果使用C#“足够快”,那么您的应用程序将更容易维护。
祝你好运!
答案 1 :(得分:4)
为获得最佳数组性能,请确保使用索引值较低的单维数组。
要尽快访问数组元素,可以使用不安全的指针,如下所示:
int[] array = Enumerable.Range(0, 1000).ToArray();
int count = 0;
unsafe {
fixed (int* pArray = array) {
for (int i = 0; i < array.Length; i++) {
count += *(pArray + i);
}
}
}
编辑 Drat!没注意到你说2D阵列。这个技巧不适用于多维数组,因此我不确定它会有多大帮助。虽然您可以通过对数组索引进行一些算术将任何数组转换为单维数组。这取决于你是否关心索引数组或迭代数组时的性能损失。
答案 2 :(得分:2)
如果您下载F#,并引用其中一个运行时库(我认为它是FSharp.PowerPack),并使用Microsoft.FSharp.Maths.Matrix。它会根据您使用密集矩阵还是稀疏矩阵来优化自身。
答案 3 :(得分:0)
您是按行还是按列或两者迭代矩阵?您是否总是访问附近的元素,或者您是否对矩阵进行随机访问。
如果您的访问中存在某些位置,但您没有顺序访问它(例如矩阵乘法中的典型值),那么您可以通过将矩阵存储在更多缓存中来获得巨大的性能差异友好的方式。
一个非常简单的方法是编写一个小的访问函数来将你的行/列索引转换为索引并处理一维矩阵,这是缓存友好的方式。
该函数应将附近的坐标分组到附近的索引中。如果你使用两种尺寸的力量,可以使用morton-order。对于非功率大小,通常可以将最低的4位带入morton顺序,并对高位使用普通的索引算法。即使索引转换的坐标看起来成本很高,你仍然可以获得显着的加速。
http://en.wikipedia.org/wiki/Z-order_(curve)&lt; - 抱歉,无法链接,因为它不喜欢带有短划线的URL。你必须削减'n'paste。
10倍以上的加速是真实的btw。这取决于你对矩阵的算法。