用整数索引执行数组表查找的最快方法是什么?

Rob*_*ock 37 c# memory lookup

我有一个移动大量数据的视频处理应用程序。

为了加快处理速度,我制作了一个查询表,因为实际上许多计算只需要计算一次即可重用。

但是,我现在所有查找都需要30%的处理时间。我想知道它是否可能是慢速RAM。但是,我仍然想尝试对其进行更多优化。

目前,我有以下内容:

public readonly int[] largeArray = new int[3000*2000];
public readonly int[] lookUp = new int[width*height];
Run Code Online (Sandbox Code Playgroud)

然后,我使用一个指针p(相当于width * y + x)执行查找以获取结果。

int[] newResults = new int[width*height];
int p = 0;
for (int y = 0; y < height; y++) {
   for (int x = 0; x < width; x++, p++) {
      newResults[p] = largeArray[lookUp[p]];
   }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我无法进行整个阵列复制以进行优化。而且,该应用程序是高度多线程的。

在缩短函数堆栈方面取得了一些进展,因此没有吸气剂,而是直接从只读数组中检索。

我也尝试过转换为ushort,但是它似乎要慢一些(据我了解,这是由于字长引起的)。

IntPtr会更快吗?我将如何处理?

下面的附件是时间分配的屏幕截图:

在此处输入图片说明

Mar*_*ell 55

看来您在这里所做的实际上是一个“聚会”。现代CPU特别为此有专门的指令VPGATHER**。这是在.NET Core 3中公开的,并且应该像下面这样工作,这是单循环方案(您可能可以从此处获得双循环版本);

结果优先:

AVX enabled: False; slow loop from 0
e7ad04457529f201558c8a53f639fed30d3a880f75e613afe203e80a7317d0cb
for 524288 loops: 1524ms

AVX enabled: True; slow loop from 1024
e7ad04457529f201558c8a53f639fed30d3a880f75e613afe203e80a7317d0cb
for 524288 loops: 667ms
Run Code Online (Sandbox Code Playgroud)

码:

AVX enabled: False; slow loop from 0
e7ad04457529f201558c8a53f639fed30d3a880f75e613afe203e80a7317d0cb
for 524288 loops: 1524ms

AVX enabled: True; slow loop from 1024
e7ad04457529f201558c8a53f639fed30d3a880f75e613afe203e80a7317d0cb
for 524288 loops: 667ms
Run Code Online (Sandbox Code Playgroud)

  • @RobotRock很棒;从1534毫秒(无AVX2)变为698毫秒(使用AVX2);更新答案 (2认同)