什么时候可以使用并行阵列?


14

我一直在尝试使用所谓的“并行数组”或列表的代码(新代码)。意味着有2个数组包含相关数据,并通过它们在数组中的位置(索引)进行链接。

我认为这很容易混淆,并且容易出现各种错误。我通常建议的解决方案是创建一个名为CompanyCompanyId和CompanyName 的对象。

一个非常真实的例子:

List<string> companyNames;
List<int> companyIds;

//...They get populated somewhere and we then process

for(var i=0; i<companyNames.Count; i++)
{
    UpdateCompanyName(companyIds[i],companyNames[i]);
}

这些并行数组是否被认为是不好的做法


9
只是进一步证明,还没有发明出无法编写Fortran的语言。
andy mango

3
进行这样的操作可能(非常重要)具有缓存优势(尽管您需要连续的数组而不是链表),这在与“面向数据的设计”相关的游戏编程中已变得颇为流行。但是,这似乎不适用于您的情况。看起来您在制作性能关键代码。
德里克·埃尔金斯

2
@DerekElkins ...有趣的是,您的评论后面有一条与Fortran代码进行了比较。Fortran的早期版本缺乏对用户定义的结构的支持,即使添加了惯用的Fortran代码也使用多个属性数组,而不是结构数组。这通常被认为是Fortran被认为是最快的语言的一部分。
Jules

3
与这个问题相关的一种思维:许多功能语言都积极鼓励使用此类列表。它们具有通常称为zip的功能,可以将它们转换为元组列表。您的代码看起来像C#。最新版本的C#增加了对一流元组的支持。因此,我想知道他们是否在某个地方添加了一个zip函数,可以自动将您的列表放入有用的结构中吗?
Jules

4
好吧,有时候有理由故意使用两个数组,但是在所有案例的99%中,我已经看到了,唯一的原因是原始作者不愿引入包容的数据结构。
布朗

Answers:


23

以下是一些人可能使用parrel数组的原因:

  1. 使用不支持类或结构的语言
  2. 当单个线程仅修改列之一时,避免线程锁定
  3. 当持久性方法强制将这些内容分开存储时,您将对其进行重构。
  4. 如果填充结构,它们可以消耗更少的内存。(不适用于C#中的这些数据类型)
  5. 当需要将部分数据保持在一起以有效利用CPU缓存时(在上面的代码中无济于事)。
  6. 使用单指令多数据(SIMD)操作码。(不适用于此代码,或根本不适用字符串)

在这种情况下,我看不出有任何令人信服的理由...而且上述所有选项中可能都有更好的选择,或者在高级语言中不太有用。


3
如果填充结构,它们也可以消耗更少的内存。与结构数组相比,智能分配的几个大型阵列消耗的内存更少。
Frank Hileman'6

4
4.当需要将部分数据保持在一起以有效利用CPU缓存时。(在极少数情况下是必需的。)
Blrfl 2015年

@Frank Hileman,Whilie我认为TheCatWhisperer的回答是完全正确的,您的评论实际上是选择此方法的最佳理由。如果内存消耗至关重要,则结构填充上的内存开销可能会非常大,尤其是在大量运行的情况下。
弗拉基米尔·斯托基奇(Fladimir Stokic)

将您的建议添加到答案
TheCatWhisperer

重新(2),那怎么样?我可以编写具有单个结构数组和每个字段一个锁的程序,就像编写具有多个数组和每个数组一个锁的程序一样容易。
所罗门慢慢片

7

我一直对使用并行数组感到内gui。有时,您会不知所措,根本不想考虑如何抽象化它。抽象可能很难重构,因此在您证明真正需要之前,您不愿意直接将其启动。

在这一点上,尽管值得考虑重构以抽象出细节。通常,我最不愿意这样做的最大原因是,很难想到一个好名字。

如果您可以看到一种很好的抽象并行数组的方法,那么每次都执行此操作。但是不要因拒绝触摸而瘫痪自己。有时,一些肮脏的代码是通向出色代码的最佳垫脚石。


6

这种模式有时也称为数组结构(与结构数组相反),在向量化代码时非常有用。除了编写在单个结构上运行并对其向量进行矢量化的计算之外,您无需像SSE内部函数那样按通常的方式编写计算,这样它就可以在4种结构上运行,而不是在一种结构上运行。这通常更容易,而且几乎总是更快。SoA格式使其非常自然。它还可以改善对齐方式,从而使SSE内存操作更快。


是的,在GPU上进行机器学习时会使用这种方法。通常将许多单独示例的字段拆开,将每个字段的所有值打包到单独的张量中,然后将这些张量传递以进行批量计算以生成预测列表。
恢复莫妮卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.