diff --git a/Makefile b/Makefile index 4606f97..a4fb675 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,8 @@ ifneq ($(OS),Windows_NT) SOURCE += $(SRC_COMMON)sysctl.c HEADERS += $(SRC_COMMON)sysctl.h endif + + SOURCE += $(SRC_DIR)sve_test.o else ifeq ($(arch), $(filter $(arch), riscv64 riscv32)) SRC_DIR=src/riscv/ SOURCE += $(COMMON_SRC) $(SRC_DIR)riscv.c $(SRC_DIR)uarch.c $(SRC_COMMON)soc.c $(SRC_DIR)soc.c $(SRC_DIR)udev.c @@ -91,6 +93,9 @@ freq_avx.o: Makefile $(SRC_DIR)freq/freq_avx.c $(SRC_DIR)freq/freq_avx.h $(SRC_D freq_avx512.o: Makefile $(SRC_DIR)freq/freq_avx512.c $(SRC_DIR)freq/freq_avx512.h $(SRC_DIR)freq/freq.h $(CC) $(CFLAGS) $(SANITY_FLAGS) -c -mavx512f -pthread $(SRC_DIR)freq/freq_avx512.c -o $@ +$(SRC_DIR)sve_test.o: Makefile $(SRC_DIR)sve_test.c + $(CC) $(CFLAGS) $(SANITY_FLAGS) -c -march=armv8-a+sve $(SRC_DIR)sve_test.c -o $@ + $(OUTPUT): Makefile $(SOURCE) $(HEADERS) ifeq ($(GIT_VERSION),"") $(CC) $(CFLAGS) $(SANITY_FLAGS) $(SOURCE) -o $(OUTPUT) diff --git a/src/arm/midr.h b/src/arm/midr.h index a133ca0..0c00ca7 100644 --- a/src/arm/midr.h +++ b/src/arm/midr.h @@ -11,6 +11,7 @@ char* get_str_features(struct cpuInfo* cpu); void print_debug(struct cpuInfo* cpu); void free_topo_struct(struct topology* topo); +void SVE_exp(struct cpuInfo* cpu); // Code taken from cpuinfo (https://github.com/pytorch/cpuinfo/blob/master/src/arm/midr.h) #define CPUINFO_ARM_MIDR_IMPLEMENTER_MASK UINT32_C(0xFF000000) diff --git a/src/arm/sve_test.c b/src/arm/sve_test.c new file mode 100644 index 0000000..cc2493f --- /dev/null +++ b/src/arm/sve_test.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include + +#ifdef __linux__ + #include + #include + #include "../common/freq.h" +#elif defined __APPLE__ || __MACH__ + #include "../common/sysctl.h" +#endif + +#include "../common/global.h" +#include "../common/soc.h" +#include "../common/args.h" +#include "udev.h" +#include "midr.h" +#include "uarch.h" + +// https://docs.kernel.org/arch/arm64/elf_hwcaps.html +void check_for_SVE(void) { + errno = 0; + long hwcaps = getauxval(AT_HWCAP); + + if(errno == ENOENT) { + printWarn("Unable to retrieve AT_HWCAP using getauxval"); + } + + if (hwcaps & HWCAP_SVE) printf("SVE: Yes\n"); + else printf("SVE: No\n"); + + hwcaps = getauxval(AT_HWCAP2); + + if (hwcaps & HWCAP2_SVE2) printf("SVE2: Yes\n"); + else printf("SVE2: No\n"); +} + +#include + +#ifndef __ARM_FEATURE_SVE +#warning "Make sure to compile for SVE!" +#endif + +// https://learn.arm.com/learning-paths/servers-and-cloud-computing/sve/sve_basics/#:~:text=Using%20a%20text%20editor%20of%20your%20choice%2C%20copy,svcntb%28%29%29%3B%20%7D%20This%20program%20prints%20the%20vector%20length +void SVE_exp(struct cpuInfo* cpu) { + check_for_SVE(); + + uint32_t core = 4; + if (!bind_to_cpu(core)) { + printErr("Failed binding the process to CPU %d", core); + return; + } + printf("[%d] SVE vector length is: %ld bytes\n", core, svcntb()); + + core = 7; + if (!bind_to_cpu(core)) { + printErr("Failed binding the process to CPU %d", core); + return; + } + printf("[%d] SVE vector length is: %ld bytes\n", core, svcntb()); + + core = 0; + if (!bind_to_cpu(core)) { + printErr("Failed binding the process to CPU %d", core); + return; + } + printf("[%d] SVE vector length is: %ld bytes\n", core, svcntb()); +} diff --git a/src/common/main.c b/src/common/main.c index f26e9aa..5e8742d 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -132,6 +132,7 @@ int main(int argc, char* argv[]) { } if(print_cpufetch(cpu, get_style(), get_colors(), show_full_cpu_name())) { + SVE_exp(cpu); return EXIT_SUCCESS; } else {