首页 > 解决方案 > 如何在 C# 中获取 AVX512?

问题描述

我想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);
}

这没有引发异常。

标签: c#simdavxavx512

解决方案


我决定为它创建自己的绑定。

你不能。您可以做的最好的事情是,用 C 或 C++ 编写一个使用 AVX512 的 DLL,并从 C# 使用 DLL。如果您尝试从 DLL 中导出单个指令,则性能不会很好,因为内存访问和 pinvoke 开销。相反,您应该在 C 中编写更大的功能。

我真的不知道我在这里做错了什么。

您的 C 函数需要寄存器中的输入指针,并在向量寄存器rcx中返回结果。zmm0

您的 C# 函数不知道zmm0. 运行时在堆栈上为返回值分配 64 个字节,在寄存器中传递返回值缓冲区的地址,在rcx寄存器中传递输入指针rdx,并期望函数返回rcxrax寄存器中传递的指针。

互操作两侧的语言在调用约定上存在分歧,并且您的代码在运行时崩溃。


推荐阅读