From 3d689c53de7fbcb8892c8d14ea5f1b8d0455af8e Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sun, 29 Sep 2013 15:24:15 +0200 Subject: [PATCH] Doesn't use extended SSE registers in the Bulldozer AMD family. --- cpu.h | 43 ++++++++++++++++++++++++++++++++++++++++++- raid.c | 9 +++++++-- speed.c | 18 ++++++++++++------ 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/cpu.h b/cpu.h index 95ec94bf..b7ec1cc9 100644 --- a/cpu.h +++ b/cpu.h @@ -119,7 +119,7 @@ static inline int cpu_has_slowmult(void) * Memory is little-endian 64-bit * Speed test with 8 disk and 262144 buffer size... * memset0 1849 [MB/s] - * HASH Murmur3 378 [MB/s] + * HASH Murmur3 378 [MB/s] (extremely slower than Spooky2) * HASH Spooky2 3413 [MB/s] * RAID5 int32x2 707 [MB/s] * RAID5 mmxx2 1264 [MB/s] @@ -138,6 +138,47 @@ static inline int cpu_has_slowmult(void) return 0; } +/** + * Check if the processor has a slow extended set of SSE registers. + * If yes, it's better to unroll without using the second part of registers. + */ +static inline int cpu_has_slowextendedreg(void) +{ + char vendor[CPU_VENDOR_MAX]; + unsigned family; + unsigned model; + + cpu_info(vendor, &family, &model); + + if (strcmp(vendor, "AuthenticAMD") == 0) { + /* AMD Bulldozer (from user) + * CPU AuthenticAMD, family 21, model 19, flags mmx sse2 + * Memory is little-endian 64-bit + * Speed test with 8 disk and 262144 buffer size, for a total of 2560 KiB... + * memset0 5721 [MB/s] + * CRC table 1080 [MB/s] + * CRC intel-crc32 2845 [MB/s] + * HASH Murmur3 2970 [MB/s] + * HASH Spooky2 7503 [MB/s] + * RAID5 int32x2 4595 [MB/s] + * RAID5 mmxx2 5856 [MB/s] + * RAID5 mmxx4 6157 [MB/s] + * RAID5 sse2x2 7151 [MB/s] + * RAID5 sse2x4 8447 [MB/s] + * RAID5 sse2x8 8155 [MB/s] (slower than sse2x4) + * RAID6 int32x2 1892 [MB/s] + * RAID6 mmxx2 3744 [MB/s] + * RAID6 sse2x2 4922 [MB/s] + * RAID6 sse2x4 4464 [MB/s] (slower than sse2x2) + */ + if (family == 21) + return 1; + } + + return 0; +} + + /* other cases */ /* Intel(R) Core(TM) i7-3740QM CPU @ 2.70GHz diff --git a/raid.c b/raid.c index 25c6fc99..9c7fa10e 100644 --- a/raid.c +++ b/raid.c @@ -2505,8 +2505,13 @@ void raid_init(void) } if (cpu_has_sse2()) { #if defined(__x86_64__) - raid5_gen = raid5_sse2r8; - raid6_gen = raid6_sse2r4; + if (cpu_has_slowextendedreg()) { + raid5_gen = raid5_sse2r4; + raid6_gen = raid6_sse2r2; + } else { + raid5_gen = raid5_sse2r8; + raid6_gen = raid6_sse2r4; + } raidTP_gen = raidTP_sse2r2; raidQP_gen = raidQP_sse2r2; #else diff --git a/speed.c b/speed.c index 4ed50bfb..3c3525e9 100644 --- a/speed.c +++ b/speed.c @@ -132,13 +132,16 @@ void speed(void) printf("Expected fastest RAID5 is "); #if defined(__i386__) || defined(__x86_64__) - if (cpu_has_sse2()) + if (cpu_has_sse2()) { #if defined(__x86_64__) - printf("sse2x8"); + if (cpu_has_slowextendedreg()) + printf("sse2x4"); + else + printf("sse2x8"); #else printf("sse2x4"); #endif - else if (cpu_has_mmx()) + } else if (cpu_has_mmx()) printf("mmxx4"); else printf("int32x2"); @@ -152,13 +155,16 @@ void speed(void) printf("Expected fastest RAID6 is "); #if defined(__i386__) || defined(__x86_64__) - if (cpu_has_sse2()) + if (cpu_has_sse2()) { #if defined(__x86_64__) - printf("sse2x4"); + if (cpu_has_slowextendedreg()) + printf("sse2x2"); + else + printf("sse2x4"); #else printf("sse2x2"); #endif - else if (cpu_has_mmx()) + } else if (cpu_has_mmx()) printf("mmxx2"); else printf("int32x2");