【问题标题】:C# reference of 2nd dim array to 1d array2nd dim 数组到 1d 数组的 C# 引用
【发布时间】:2017-07-21 16:06:07
【问题描述】:

我有一个函数可以将 1d 数组 (double[]) 作为参数,而我的源数据是 2d 数组 (double[,]) 的“cnt”个 3d 点,就像这样

double[,] points = new double[3,cnt]

但我真正想做的是将三个 2nd dim 数组中的每一个传递给函数gpu.Average(double[] arg),最好不必通过 value[i] 复制数组 value[i] 的内容。这在 C# 中可行吗?

示例代码

这行得通:

double[] points1d = new double[cnt];
// ... fill points1d with data, then
double a = gpu.Average(points1d);  // <- Alea.gpu.Average() accepts a 1d array 

但如前所述,我想将第二维传递给函数 gpu.Average() 而不必运行 for 循环三次以复制到一维数组中:

double[,] points2d = new double[3,cnt];
// ... fill points2d with 'cnt' items of data and
// then pass it on

double x = gpu.Average(points2d[0,??]);  // How to pass on 2nd dim?
double y = gpu.Average(points2d[1,??]);     
double z = gpu.Average(points2d[2,??]);     

这是否可能无需将数据复制到一维数组中?

(顺便说一句,计算平均值并不是使用 gpu 并行库的一个很好的示例,这只是一个比较不同数据类型和结构的执行时间的测试用例)。

// 罗尔夫

【问题讨论】:

  • 不,但是如果您使用嵌套数组 ([][]) 而不是二维数组 ([,]),那么您可以。
  • 嗯。但是嵌套数组可以分配动态长度吗?我在想double[3][someList.Count];
  • 如果你非常幸运,那么你的方法将会有一个重载,它需要一个 double* 而不是一个数组。然后你就可以这样做了。
  • 它们可以随意分配,但它比二维数组更多的代码。你必须显式地创建每个数组,所以你需要一个 for 循环。
  • 您可以固定数组并覆盖其对象头,使其看起来像一个适当长度的一维数组(对于第一个数组)。对于后面的数组,您可以临时覆盖先前数组的最后一个元素,然后使用一些 CIL 代码重新解释将您写入的方法表指针转换为一维数组类型的托管引用。

标签: c# arrays


【解决方案1】:

不,这在托管代码中是不可能的,而不复制例如的内容。 points2d[1,*] 到一个新的一维数组。

在托管代码中,每个数组都必须知道它的长度,以便可以检查每个索引访问,如果索引超出范围,则会引发 ArrayIndexOutOfBounds 异常。长度(整数值)存储在数组的第一个元素之前,以便运行时知道在哪里找到它。现在有了这个,我想人们可以明白为什么你不能将数组分成几个部分并将它们视为新数组。请注意,对于多维数组来说,情况就更复杂了,它必须存储维数和每个维的大小......

你可以做的是使用锯齿数组:

double[][] points2d = new double[3][];
points2[0] = new double[cnt];
...
gpu.Average(points2d[0]);

锯齿状数组比多维数组更快,建议使用而不是多维数组even by MS

【讨论】:

  • +1,虽然实际上可以使用托管代码来执行此操作,但是这样做所需的代码是残酷的,并且如果在执行恶作剧时发生 GC,则会严重崩溃。当然,您可以在期间阻止 GC,但不适合胆小的人。
  • 你能链接到一个 MS 参考资料,说锯齿状数组比多维数组更推荐吗?
  • 不幸的是,该代码无法编译。编辑:不过,我将使用double[][] points2d = new double[3][]; 进行测试。 bb
  • 好的,重复创建另外三个数组 [3][...] 有效。这与创建三个离散数组基本相同。在这种情况下,所有这些分配所花费的时间比 CPU 直接完成这项工作所花费的时间长 10 倍,但这个技巧在其他情况下可能会被证明是有用的。它有效,所以我会接受这个作为答案。非常感谢!编辑:您可以将最后缺少的方括号添加到代码示例new double[3][];。 :)
  • 该参考文献似乎只讨论了锯齿状数组可以节省空间的情况; “如果多维数组不浪费空间,则禁止此规则发出警告。” - 在这种情况下适合 OP 的代码。有趣的是,对于这样一个特定且(我本以为)不寻常的情况,他们完全有这个警告。
猜你喜欢
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
  • 2011-02-05
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 2023-02-21
相关资源
最近更新 更多