From 5fb2be86a72ccae7ae49a116a5c6eb2808560937 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Sun, 13 Apr 2025 09:02:51 -0500 Subject: [PATCH] feat(simd): added function to check what simd version is supported --- Include/Hallocy/Utils/Simd.h | 18 ++++++ Src/Utils/Simd.c | 111 ++++++++++++++++++++++++++++++++++- Tests/Main.c | 5 +- 3 files changed, 132 insertions(+), 2 deletions(-) diff --git a/Include/Hallocy/Utils/Simd.h b/Include/Hallocy/Utils/Simd.h index d7ba37d..3860e58 100644 --- a/Include/Hallocy/Utils/Simd.h +++ b/Include/Hallocy/Utils/Simd.h @@ -23,6 +23,22 @@ #ifndef HALLOCY_SIMD #define HALLOCY_SIMD +#if defined(_MSC_VER) + #if defined(_M_ARM64) + #include + #else + #include + #endif +#else + #if defined(__aarch64__) + #include + #elif defined(__arm__) + #include + #else + #include + #endif +#endif + typedef enum { HALLOCY_SIMD_UNDEFINED = 0, HALLOCY_SIMD_NONE = 1, @@ -34,4 +50,6 @@ typedef enum { HALLOCY_SIMD_NEON = 7 } HallocySimdType; +HallocySimdType hallocy_is_simd_supported(); + #endif \ No newline at end of file diff --git a/Src/Utils/Simd.c b/Src/Utils/Simd.c index 8309e77..b06de6a 100644 --- a/Src/Utils/Simd.c +++ b/Src/Utils/Simd.c @@ -21,4 +21,113 @@ */ #include "../../Include/Hallocy/Utils/Simd.h" -static HallocySimdType supported_simd = HALLOCY_SIMD_UNDEFINED; \ No newline at end of file +static HallocySimdType hallocy_supported_simd = HALLOCY_SIMD_UNDEFINED; + +HallocySimdType hallocy_is_simd_supported() { + if (hallocy_supported_simd != HALLOCY_SIMD_UNDEFINED) { + return hallocy_supported_simd; + } + + #if defined(_MSC_VER) + #if defined(_M_ARM64) + if (isProcessorFeaturePresent(PF_ARM64_SVE)) { + hallocy_supported_simd = HALLOCY_SIMD_NEON; + return hallocy_supported_simd; + } + #else + int cpu_info[4] = { 0 }; + __cpuid(cpu_info, 7); + if ((cpu_info[1] & (1 << 16)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX512; + return hallocy_supported_simd; + } + + if ((cpu_info[1] & (1 << 5)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX2; + return hallocy_supported_simd; + } + + __cpuid(cpu_info, 1); + + if ((cpu_info[2] & (1 << 28)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX; + return hallocy_supported_simd; + } + + if ((cpu_info[3] & (1 << 26)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_SSE2; + return hallocy_supported_simd; + } + + if ((cpu_info[3] & (1 << 25)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_SSE2; + return hallocy_supported_simd; + } + #endif + #else + #if defined(__aarch64__) || defined(__arm__) + int file_descriptor = open("/proc/cpuinfo", O_READONLY); + if (file_descriptor == -1) { + return hallocy_supported_simd; + } + + char buffer[256]; + int bytes_read = read(file_descriptor, buffer, sizeof(buffer)); + while (bytes_read > 0) { + for (size_t i = 0; i < bytes_read - 4; i++) { + if (buffer[i] == 'n' && buffer[i + 1] == 'e' && buffer[i + 2] == 'o' && buffer[i + 3] == 'n') { + close(file_descriptor); + + hallocy_supported_simd = HALLOCY_SIMD_NEON; + return hallocy_supported_simd; + } + } + + bytes_read = read(file_descriptor, buffer, sizeof(buffer)); + } + + close(file_descriptor); + #else + unsigned int a, b, c, d; + __asm__ __volatile__ ( + "cpuid" + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) + : "a" (7) + ); + + if ((b & (1 << 16)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX512; + return hallocy_supported_simd; + } + + if ((b & (1 << 5)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX2; + return hallocy_supported_simd; + } + + __asm__ __volatile__ ( + "cpuid" + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) + : "a" (1) + ); + + if ((c & (1 << 28)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_AVX; + return hallocy_supported_simd; + } + + if ((c & (1 << 26)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_SSE2; + return hallocy_supported_simd; + } + + if ((c & (1 << 25)) != 0) { + hallocy_supported_simd = HALLOCY_SIMD_SSE; + return hallocy_supported_simd; + } + #endif + #endif + + hallocy_supported_simd = HALLOCY_SIMD_NONE; + return hallocy_supported_simd; +} \ No newline at end of file diff --git a/Tests/Main.c b/Tests/Main.c index 2978a7d..f345485 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -21,7 +21,8 @@ */ #include #include - + #include + int main() { char *memory = (char *)hallocy_malloc(12288); if (memory == NULL) { @@ -40,5 +41,7 @@ return -1; } + printf("Supported simd version: %d\n", hallocy_is_simd_supported()); + return 0; } \ No newline at end of file