10

在对数组中的元素执行大量算术运算时,在 C# 中存储二维数组以优化性能的最佳方法是什么?

我们有大型(大约 1.5G)数组,例如,我们希望将它们逐个元素地相乘。性能至关重要。执行此操作的上下文在 c# 中。有什么聪明的方法来存储数组并迭代它们吗?我们可以用非托管 C++ 编写这些部分吗?这真的会提高性能吗?数组需要可供 c# 程序的其余部分访问。

目前(在 c 中)该数组存储为单个长向量。我们对数组中的每个元素执行计算并覆盖旧值。对于向量中的每个元素,计算通常是唯一的。

时序实验表明,在 C# 中将数据作为数组存储和迭代比将其存储为 2D 数组要慢。我想知道是否有更好的数据处理方式。执行的具体算术与问题无关。

4

4 回答 4

8

安娜,

这是一个很棒的页面,讨论了传统科学编程语言(fortran、C++)和 c# 之间的性能差异。

http://msdn.microsoft.com/en-us/magazine/cc163995.aspx

根据文章 C#,当使用矩形数组 (2d) 时,性能非常好。这是一个图表,显示了锯齿状数组(数组的数组)和矩形数组(多维)数组之间的性能差异。

替代文字 http://i.msdn.microsoft.com/cc163995.fig08.gif

我建议自己进行试验,并使用 VS 2008 中的性能分析进行比较。

如果使用 C#“足够快”,那么您的应用程序将更容易维护。

祝你好运!

于 2008-09-21T13:55:06.950 回答
5

为获得最佳数组性能,请确保您使用的是较低索引为 0 的一维数组。

要尽可能快地访问数组的元素,可以使用不安全的指针,如下所示:

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);
        }
    }
}

EDIT Drat! Didn't notice you said 2D array. This trick won't work with a multi-dimensional array so I'm not sure how much help it will be. Although you could turn any array into a single-dimension array by doing some arithmetic on the array index. Just depends on if you care about the performance hit in indexing the array or in iterating over the array.

于 2008-09-21T13:46:42.727 回答
2

如果您下载 F#,并引用其中一个运行时库(我认为是 FSharp.PowerPack),并使用 Microsoft.FSharp.Maths.Matrix。它会根据您使用的是密集矩阵还是稀疏矩阵进行自我优化。

于 2008-09-21T14:03:12.157 回答
0

Do you iterate the matrix by row or by colum or both? Do you always access nearby elements or do you do random accesses on the matrix.

If there is some locality in your accesses but you're not accessing it sequential (typical in matrix multiplication for example) then you can get a huge performance difference by storing your matrix in a more cache-friendly way.

A pretty easy way to do that is to write a little access function to turn your row/colum indices into an index and work on a one dimensional matrix, the cache-friendy way.

The function should group nearby coordinates into nearby indices. The morton-order can be used if you work on power of two sizes. For non-power sizes you can often bring just the lowest 4 bits into morton order and use normal index-arithmetic for the upper bits. You'll still get a significant speed-up, even if the coordinate to index conversion looks seems to be a costly operation.

http://en.wikipedia.org/wiki/Z-order_(curve) <-- sorry, can't link that SO does not like URL's with a dash in it. You have to cut'n'paste.

A speed up of factor 10 and more are realistic btw. It depends on the algorithm you ron over your matrices though.

于 2008-09-21T14:37:18.940 回答