diff --git a/HISTORY b/HISTORY index cd480d76..11e069f6 100644 --- a/HISTORY +++ b/HISTORY @@ -18,6 +18,12 @@ SnapRAID HISTORY intelligently mixes live access for the disks being repaired with snapshot access for reference disks to maintain mathematical integrity across the array. + * Implemented AVX-512BW (Byte and Word) support for parity generation + and data recovery, optimizing performance on modern architectures + like Intel Sapphire Rapids and AMD Zen 4/5. + By scaling to 512-bit ZMM registers, the implementation now processes + 64 bytes per iteration, effectively doubling the data width of the + previous AVX2 routines. 14.10 2026/08 ============= diff --git a/cmdline/speed.c b/cmdline/speed.c index 10ae8c8b..fe993bc5 100644 --- a/cmdline/speed.c +++ b/cmdline/speed.c @@ -284,6 +284,7 @@ void speed(int period, int nd, int size) printf("%8s", "avx2"); #ifdef CONFIG_X86_64 printf("%8s", "avx2e"); + printf("%8s", "avx512"); #endif #endif printf("\n"); @@ -338,6 +339,19 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_X86_64 + printf("%8s", ""); +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + raid_gen1_avx512bw(nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif +#endif #endif printf("\n"); @@ -397,6 +411,19 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_X86_64 + printf("%8s", ""); +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + raid_gen2_avx512bw(nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif +#endif #endif printf("\n"); @@ -522,6 +549,16 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + raid_gen3_avx512bw(nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif #endif #endif printf("\n"); @@ -587,6 +624,16 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + raid_gen4_avx512bw(nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif #endif #endif printf("\n"); @@ -652,6 +699,16 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + raid_gen5_avx512bw(nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif #endif #endif printf("\n"); @@ -717,6 +774,16 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + raid_gen6_avx512bw(nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif #endif #endif printf("\n"); @@ -730,6 +797,9 @@ void speed(int period, int nd, int size) #ifdef CONFIG_X86 printf("%8s", "ssse3"); printf("%8s", "avx2"); +#ifdef CONFIG_X86_64 + printf("%8s", "avx512"); +#endif #endif printf("\n"); @@ -774,6 +844,21 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_X86_64 +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + /* ensure to use same hardware in the delta step */ + raid_gen_force(1, raid_gen1_avx512bw); + /* +1 to avoid GEN1 optimized case */ + raid_rec1_avx512bw(1, id, ip + 1, nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif +#endif #endif printf("\n"); @@ -814,7 +899,7 @@ void speed(int period, int nd, int size) SPEED_START { /* ensure to use same hardware in the delta step */ raid_gen_force(2, raid_gen2_avx2); - /* +1 to avoid GEN1 optimized case */ + /* +1 to avoid GEN2 optimized case */ raid_rec2_avx2(2, id, ip + 1, nd, size, v); } SPEED_STOP @@ -822,6 +907,21 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_X86_64 +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + /* ensure to use same hardware in the delta step */ + raid_gen_force(2, raid_gen2_avx512bw); + /* +1 to avoid GEN2 optimized case */ + raid_rec2_avx512bw(2, id, ip + 1, nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif +#endif #endif printf("\n"); @@ -871,6 +971,21 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_X86_64 +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + /* ensure to use same hardware in the delta step */ + raid_gen_force(3, raid_gen3_avx512bw); + /* +1 to avoid GEN1 optimized case */ + raid_recX_avx512bw(3, id, ip, nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif +#endif #endif printf("\n"); @@ -921,6 +1036,21 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_X86_64 +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + /* ensure to use same hardware in the delta step */ + raid_gen_force(4, raid_gen4_avx512bw); + /* +1 to avoid GEN1 optimized case */ + raid_recX_avx512bw(4, id, ip, nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif +#endif #endif printf("\n"); @@ -970,6 +1100,21 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_X86_64 +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + /* ensure to use same hardware in the delta step */ + raid_gen_force(5, raid_gen5_avx512bw); + /* +1 to avoid GEN1 optimized case */ + raid_recX_avx512bw(5, id, ip, nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif +#endif #endif printf("\n"); @@ -1019,6 +1164,21 @@ void speed(int period, int nd, int size) fflush(stdout); } #endif +#ifdef CONFIG_X86_64 +#ifdef CONFIG_AVX512BW + if (raid_cpu_has_avx512bw()) { + SPEED_START { + /* ensure to use same hardware in the delta step */ + raid_gen_force(6, raid_gen6_avx512bw); + /* +1 to avoid GEN1 optimized case */ + raid_recX_avx512bw(6, id, ip, nd, size, v); + } SPEED_STOP + + printf("%8" PRIu64, ds / dt); + fflush(stdout); + } +#endif +#endif #endif printf("\n"); printf("\n");