我需要创建一个与 64 字节边界对齐的数组。我需要这样做,因为我正在调用一个使用AVX的 DLL ,这需要对齐数据。本质上我需要在 C# 中执行此操作:
void* ptr = _aligned_malloc(64 * 1024, 64);
int8_t* memory_ptr = (int8_t*)ptr;
Run Code Online (Sandbox Code Playgroud)
我很确定我无法在 C# 中自然地创建这样一个边界的数组。因此,一种选择是创建一个 x+64 长的字节数组,然后“创建”一个覆盖它的数组,但在所需边界处有一个偏移量。
问题是如何实现这一点,并且不会出现内存泄漏?(内存泄漏是我不想使用 DLL 创建对数组的引用并将其传递给 C# 的原因。除非有一个好的方法可以这样做?)
使用下面有用的答案,这就是我所拥有的,希望它对其他人有帮助:
public class Example : IDisposable
{
private ulong memory_ptr;
public unsafe Example()
{
memory_ptr = (ulong)NativeMemory.AlignedAlloc(0x10000, 64);
}
public unsafe Span<byte> Memory => new Span<byte>((void*)memory_ptr, 0x10000);
public unsafe void Dispose()
{
NativeMemory.Free((void*)memory_ptr);
}
}
Run Code Online (Sandbox Code Playgroud)
如前所述,.NET 6 有NativeMemory.AlignedAlloc. 您需要确保打电话,AlignedFree否则可能会发生泄漏。
void* a = default;
try
{
a = NativeMemory.AlignedAlloc(size * sizeof(long), 64);
var span = new Span<long>(a, size);
// fill span
// call DLL with span
}
finally
{
NativeMemory.AlignedFree(a);
}
Run Code Online (Sandbox Code Playgroud)
固定GCHandle是旧版本 .NET 的另一种选择。然后,您需要使用以下代码计算起始对齐偏移量(在您的情况下alignment)64。
var ptr = (long)handle.AddrOfPinnedObject();
var offset = (int) ((ptr + alignment - 1) / alignment * alignment - ptr) / sizeof(long);
Run Code Online (Sandbox Code Playgroud)
同样,您需要确保handle.Free调用finally.
| 归档时间: |
|
| 查看次数: |
718 次 |
| 最近记录: |