diff --git a/cmdline/speed.c b/cmdline/speed.c index 4edc0e52..8f52f1f7 100644 --- a/cmdline/speed.c +++ b/cmdline/speed.c @@ -119,11 +119,13 @@ void speed(int period, int nd, int size) raid_cpu_info(vendor, &family, &model); - printf("CPU %s, family %u, model %u, flags%s%s%s%s%s%s\n", vendor, family, model, + printf("CPU %s, family %u, model %u, flags%s%s%s%s%s%s%s%s\n", vendor, family, model, raid_cpu_has_sse2() ? " sse2" : "", raid_cpu_has_ssse3() ? " ssse3" : "", raid_cpu_has_crc32() ? " crc32" : "", raid_cpu_has_avx2() ? " avx2" : "", + raid_cpu_has_avx512bw() ? " avx512bw" : "", + raid_cpu_has_avx512gfni() ? " avx512gfni" : "", raid_cpu_has_slowmult() ? " slowmult" : "", raid_cpu_has_slowextendedreg() ? " slowext" : "" ); diff --git a/raid/cpu.h b/raid/cpu.h index 5325e19b..886d82eb 100644 --- a/raid/cpu.h +++ b/raid/cpu.h @@ -85,7 +85,7 @@ static inline int raid_cpu_match_sse(uint32_t cpuid_1_ecx, uint32_t cpuid_1_edx) return 1; } -static inline int raid_cpu_match_avx(uint32_t cpuid_1_ecx, uint32_t cpuid_7_ebx, uint32_t xcr0) +static inline int raid_cpu_match_avx(uint32_t cpuid_1_ecx, uint32_t cpuid_7_ebx, uint32_t cpuid_7_ecx, uint32_t xcr0) { uint32_t reg[4]; @@ -101,6 +101,9 @@ static inline int raid_cpu_match_avx(uint32_t cpuid_1_ecx, uint32_t cpuid_7_ebx, if ((reg[1] & cpuid_7_ebx) != cpuid_7_ebx) return 0; + if ((reg[2] & cpuid_7_ecx) != cpuid_7_ecx) + return 0; + return 1; } @@ -174,9 +177,10 @@ static inline int raid_cpu_has_avx2(void) * also detect support for AVX2 by checking CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5]. */ return raid_cpu_match_avx( - (1 << 27) | (1 << 28), /* OSXSAVE and AVX */ - 1 << 5, /* AVX2 */ - 3 << 1); /* OS saves XMM and YMM registers */ + (1 << 27) | (1 << 28), /* Leaf 1, ECX: XSAVE and AVX */ + 1 << 5, /* Leaf 7, EBX: AVX2 */ + 0, /* Leaf 7, ECX: */ + 3 << 1); /* XCR0: OS saves XMM and YMM registers */ } static inline int raid_cpu_has_avx512bw(void) @@ -196,9 +200,20 @@ static inline int raid_cpu_has_avx512bw(void) /* note that intentionally we don't check for AVX and AVX2 */ /* because the documentation doesn't require that */ return raid_cpu_match_avx( - 1 << 27, /* XSAVE/XGETBV */ - (1 << 16) | (1 << 30), /* AVX512F and AVX512BW */ - (3 << 1) | (7 << 5)); /* OS saves XMM, YMM and ZMM registers */ + 1 << 27, /* Leaf 1, ECX: XSAVE/XGETBV */ + (1 << 16) | (1 << 30), /* Leaf 7, EBX: AVX512F and AVX512BW */ + 0, /* Leaf 7, ECX: */ + (3 << 1) | (7 << 5)); /* XCR0: OS saves XMM, YMM and ZMM registers */ +} + +static inline int raid_cpu_has_avx512gfni(void) +{ + return raid_cpu_match_avx( + 1 << 27, /* Leaf 1, ECX: XSAVE/XGETBV */ + 1 << 16, /* Leaf 7, EBX: AVX512F (Foundation) */ + 1 << 8, /* Leaf 7, ECX: GFNI */ + (3 << 1) | (7 << 5) /* XCR0: OS saves XMM, YMM and ZMM registers */ + ); } /**