feat(simd): added function to check what simd version is supported

This commit is contained in:
Mineplay 2025-04-13 09:02:51 -05:00
parent 76e5cff6a1
commit 5fb2be86a7
3 changed files with 132 additions and 2 deletions

View file

@ -23,6 +23,22 @@
#ifndef HALLOCY_SIMD
#define HALLOCY_SIMD
#if defined(_MSC_VER)
#if defined(_M_ARM64)
#include <arm64intr.h>
#else
#include <intrin.h>
#endif
#else
#if defined(__aarch64__)
#include <arm64intr.h>
#elif defined(__arm__)
#include <arm_neon.h>
#else
#include <immintrin.h>
#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

View file

@ -21,4 +21,113 @@
*/
#include "../../Include/Hallocy/Utils/Simd.h"
static HallocySimdType supported_simd = HALLOCY_SIMD_UNDEFINED;
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;
}

View file

@ -21,7 +21,8 @@
*/
#include <stdio.h>
#include <Hallocy/Core/Allocator.h>
#include <Hallocy/Utils/Simd.h>
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;
}