我想在AVX-512中使用C#指令,但我所理解的是:对它没有支持(或者我在网上搜索方面非常糟糕)。所以我决定为它创建自己的绑定。但我得到的是:
外部组件引发了异常。
我不知道我在这里搞砸了什么。
以下是我的C代码:
#include <immintrin.h>
__declspec(dllexport)
__m512i
load_s32(const void *ptr) {
return _mm512_load_epi32(ptr);
}它使用以下命令进行编译:
gcc -c decl.c -mavx512f
gcc -shared -o libavx512.dll decl.o -Wl,--out-implib,libavx512.dll.a -mavx512f在C#中,我创建了一个库,它包含以下部分:
using System.Runtime.InteropServices;
using S64 = System.Int64;
namespace AVX512Sharp
{
[StructLayout(LayoutKind.Sequential, Size = 64)]
public struct M512S32
{
public S64 M0;
public S64 M1;
public S64 M2;
public S64 M3;
public S64 M4;
public S64 M5;
public S64 M6;
public S64 M7;
}
public static class AVX512
{
[DllImport("libavx512.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "load_s32")]
public extern unsafe static M512S32 LoadS32(void* ptr);
}
}在我的测试程序中,我像这样使用它:
int* mem = stackalloc int[16];
for (int i = 0; i < 16; ++i)
mem[i] = i * 10;
M512S32 zmm0;
zmm0 = AVX512.LoadS32(mem);我真的不知道我做错了什么。
备注
__declspec(dllexport)
void
load_s32(const void *ptr) {
return;
}还更新了AVX512类:
public static class AVX512
{
[DllImport("libavx512.dll", EntryPoint = "load_s32")]
public extern unsafe static void LoadS32(void* ptr);
}这并没有抛出异常。
dll应用程序中使用C。结果也没有任何错误。-Wl,--export-all-symbols、-Wl,--enable-auto-import。相关的文档是这里。发布于 2021-04-25 06:37:19
我决定为它创建自己的绑定。
最好的方法是用C或C++编写一个使用AVX512的DLL,然后从C#中使用DLL。如果您试图从DLL导出单独的指令,性能将不会很好,因为内存访问和pinvoke开销。相反,您应该用C编写更大的功能片段。
我真的不知道我做错了什么。
您的C函数需要rcx寄存器中的输入指针,并返回zmm0向量寄存器的结果。
您的C#函数不了解zmm0。运行时在堆栈上为返回值分配64个字节,在rcx寄存器中传递返回值缓冲区的地址,在rdx寄存器中传递输入指针,并期望函数返回rcx在rax寄存器中传递的指针。
互操作双方的语言在调用约定上存在分歧,您的代码在运行时崩溃。
https://stackoverflow.com/questions/67246318
复制相似问题