Arrays 复制大数组或更改访问索引

Arrays 复制大数组或更改访问索引,arrays,performance,fortran,Arrays,Performance,Fortran,如果这个问题有一个明显的答案,我表示歉意,但我不能用恰当的措辞在网上找到答案 在Fortran中,假设我有一个实数数组(>100000)。在时间积分方案的一个步骤中,我将不断地(以连续的方式)反复访问此阵列。每个后续步骤都不再需要此数组的某些元素。我不知道有多少人,可能在任何地方,从没有人到所有人。我的问题是: 最好是:(1)每一步都检查这个数组,并将我需要的剩余元素复制到一个新数组中,即使可能只需要取出很小的百分比,还是(2)我应该有一个整数索引的新数组,我会每一个时间步更新它来访问这个数组。

如果这个问题有一个明显的答案,我表示歉意,但我不能用恰当的措辞在网上找到答案

在Fortran中,假设我有一个实数数组(>100000)。在时间积分方案的一个步骤中,我将不断地(以连续的方式)反复访问此阵列。每个后续步骤都不再需要此数组的某些元素。我不知道有多少人,可能在任何地方,从没有人到所有人。我的问题是:

最好是:(1)每一步都检查这个数组,并将我需要的剩余元素复制到一个新数组中,即使可能只需要取出很小的百分比,还是(2)我应该有一个整数索引的新数组,我会每一个时间步更新它来访问这个数组。我的理解是,如果内存访问是连续的,它应该非常快,我认为这应该超过复制阵列的成本。另一方面,更新整数索引的速度会非常快,但代价是数据会被分割,访问速度会变慢


或者这是一个没有明确答案的问题,我需要去测试这两种方法,以找出哪种更适合我的应用程序

事先很难说,所以简单的答案确实是*“测量!”
不过,一些猜测可能有助于衡量什么。在假设代码确实是性能关键的情况下,接下来的一切

内存延迟:
100k元素通常会超过一级和二级缓存,因此内存局部性将发挥作用。OTOH,线性扫描比散射访问要好得多

如果与每个元素的操作相比,内存延迟是显著的,并且在给定的迭代次数后,大多数元素变得“无趣”,那么我的目标是:

  • 将单个元素标记为“在将来的迭代中跳过”
  • 当约50%的元素可跳过时,压缩内存(即删除可跳过的元素)
(测试上述条件:对于一个简单的实现,单个迭代的时间是否比元素数量的线性增长快?)

缓存友好块:
如果内存延迟是一个问题,并且可以对一个小数据块(比如32KiB的数据)应用多个操作,那么就这样做

并行化:

(房间里的大象)。如果可以在缓存友好的块中进行处理,则可以轻松添加。

显示真实代码总比用文字进行长描述要好。它太长,太无聊,太暧昧。(TLDR)我怀疑这里的答案确实是试试看。根据我的经验,使用查找数组进行索引可能会导致性能显著降低。另一种方法是实现一个链表,您可以在删除元素时对其进行更新,但我怀疑这也会导致性能下降——但我认为这实际上取决于您的特定用例。我非常喜欢标记元素,然后在达到阈值后进行清理的想法。这似乎是两全其美!我很想看到结果,是否有任何不同等等。!