gpt4 book ai didi

c# - 如何表示 Span 列表/数组

转载 作者:行者123 更新时间:2023-12-05 06:31:28 25 4
gpt4 key购买 nike

我想交错放置多个内存/跨度缓冲区。是否可以在不重复访问内部循环中的 Span 属性的情况下执行此操作?

public static void Interleave(StreamWriter s, ReadOnlyMemory<float>[] data)
{
for (int i = 0; i < data.First().Length; i++)
{
for (int j = 0; j < data.Length; j++)
{
s.Write(data[j].Span[i]);
}
}
}

最佳答案

我没有找到表示 Span<int>[] 的方法或 Span<Span<int>> , 但我使用递归不安全函数来实现与 int** 类似的结果指针。不幸的是,它不能很好地泛化。

|                 Method |     Mean |     Error |    StdDev |
|----------------------- |---------:|----------:|----------:|
| InterleaveArray | 1.405 ms | 0.0125 ms | 0.0111 ms |
| InterleaveMemorySpan | 4.232 ms | 0.0659 ms | 0.0616 ms |
| UnsafeInterleaveMemory | 1.374 ms | 0.0143 ms | 0.0134 ms |

请注意,重复访问 Memory 上的 Span 属性比其他两个实现慢 3 倍。这是我使用的代码:

public class InterleaveTests
{
private Action<int> act = x => { };
public static int[][] CreateBuffers(int BufferCount, int BufferSize)
{
return Enumerable.Range(0, BufferCount)
.Select(i => Enumerable.Range(0, BufferSize)
.Select(j => j * BufferCount + i).ToArray()).ToArray();
}

[Benchmark]
[ArgumentsSource(nameof(MemoryNumbers))]
public void InterleaveMemorySpan(Memory<int>[] data)
{
var rows = data.First().Length;
for (int i = 0; i < rows; i++)
for (int j = 0; j < data.Length; j++)
act(data[j].Span[i]);
}

[Benchmark]
[ArgumentsSource(nameof(MemoryNumbers))]
public unsafe void UnsafeInterleaveMemory(Memory<int>[] data)
{
var dataBuffers = stackalloc int*[data.Length];
Pin(data.AsSpan(), 0);

void Pin(Span<Memory<int>> buffers, int bufferIndex)
{
if (buffers.Length == 0)
{
InterleaveMemory(data.First().Length, data.Length, dataBuffers);
}
else
{
fixed (int* pData = buffers[0].Span)
{
dataBuffers[bufferIndex] = pData;
Pin(buffers.Slice(1), bufferIndex + 1);
}
}
}

void InterleaveMemory(int rows, int columns, int** dataSpans)
{
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
act(dataSpans[j][i]);
}
}


[Benchmark]
[ArgumentsSource(nameof(ArrayNumbers))]
public void InterleaveArray(int[][] data)
{
var rows = data.First().Length;
for (int i = 0; i < rows; i++)
for (int j = 0; j < data.Length; j++)
act(data[j][i]);
}

public IEnumerable<int[][]> ArrayNumbers()
{
yield return CreateBuffers(16, 32 * 1024);
}

public IEnumerable<Memory<int>[]> MemoryNumbers()
{
yield return CreateBuffers(16, 32 * 1024).Select(x => x.AsMemory()).ToArray();
}
}

关于c# - 如何表示 Span<T> 列表/数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51828954/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com