我想我可能已经找到了使用
Unsafe
同学们,我已经测试过了,到目前为止,它似乎是有效的。这是:
public static unsafe void Fill<T>(this Span<T> span, [NotNull] Func<T> provider) where T : struct
{
int
cores = Environment.ProcessorCount,
batch = span.Length / cores,
mod = span.Length % cores,
size = Unsafe.SizeOf<T>();
ref T r0 = ref span.DangerousGetPinnableReference();
fixed (byte* p0 = &Unsafe.As<T, byte>(ref r0))
{
byte* p = p0;
Parallel.For(0, cores, i =>
{
byte* pi = p + i * batch * size;
for (int j = 0; j < batch; j++, pi += size)
Unsafe.Write(pi, provider());
}).AssertCompleted();
// Remaining values
if (mod < 1) return;
for (int i = span.Length - mod; i < span.Length; i++)
Unsafe.Write(p + i * size, provider());
}
}
基本上,因为我不能固定
ref T
价值,我试着
ref byte
变量使用
Unsafe.As<T, byte>(ref T value)
而是把那个钉上。由于它指向相同的地址,我认为(希望)它被钉住了,它应该在IL中做同样的事情。