首页 > 解决方案 > 如何根据数组索引从数组复制到 Vector256,反之亦然?

问题描述

假设我有一个int[]数组或Vector256<int>s。如何使用数组索引将值从一个复制到另一个?

目前我必须遍历数组索引并一一复制值:

int[] input = ...; // length divisible by Vector256<int>.Count
int[] output = new int[intput.Length];

for (int i = 0; i < input.Length; i += Vector256<int>.Count)
{
    Vector256<int> v = Vector256.Create(
                array[i], array[i + 1], array[i + 2], array[i + 3],
                array[i + 4], array[i + 5], array[i + 6], array[i + 7]);

    Vector256<int> v2 = DoSomeWork(v);

    for (int j = 0; j < Vector256<int>.Count; ++j)
    {
        output[i + j] = v2.GetElement(i + j);
    }
}

在 Java SDK 16 中,有些函数可以完全满足我的需要。C#中是否有类似的功能?

int[] input = ...;
int[] output = new int[values.length];

for (int i = 0; i < input.length; i += IntVector.SPECIES_256.length()) {
    IntVector v = IntVector.fromArray(IntVector.SPECIES_256, input, i);
    IntVector v2 = DoSomeWork(v);
    v2.intoArray(output, i);
}

标签: c#.netsimdavx2

解决方案


另一种解决方案。

int[] input = ...;
int[] output = new int[input.Length];
Span<Vector256<int>> inputVectors = MemoryMarshal.Cast<int, Vector256<int>>(input);
Span<Vector256<int>> outputVectors = MemoryMarshal.Cast<int, Vector256<int>>(output);
for (int i = 0; i < inputVectors.Length; i++)
    outputVectors[i] = DoSomeWork(inputVectors[i]); 

结果将自动在output数组中。

不安全的版本

int[] input = ...;
int[] output = new int[input.Length];
fixed (int* inPtr = input, outPtr = output)
{
    Vector256<int>* src = (Vector256<int>*)inPtr;
    Vector256<int>* dst = (Vector256<int>*)outPtr;
    Vector256<int>* srcEnd = src + (input.Length >> 3);
    while (src < srcEnd)
    {
        *dst = DoSomeWork(*src);
        src++;
        dst++;
    }
}

所有 3 种解决方案:从公认的答案来看是不安全的,并且上述两种解决方案的性能几乎相同。


推荐阅读