Default to AVX2_256 SIMD for Zen2
authorErik Lindahl <erik.lindahl@gmail.com>
Thu, 22 Aug 2019 21:42:15 +0000 (23:42 +0200)
committerPaul Bauer <paul.bauer.q@gmail.com>
Fri, 23 Aug 2019 11:45:12 +0000 (13:45 +0200)
From Zen2, we should no longer use the previous
hack with 128-bit AVX2 since the microarchitecture
can now execute two full-width AVX2 instructions
per cycle. Rather than specializing for Zen2, the
logic has been changed so we only apply the 128-bit
optimization for the chips where we know it helps
(Zen and Zen+, based on the model numbers), while
we default to full-width AVX2 for all other AMD
CPUs - which for now is only Zen2.

Fixes #3061.

Change-Id: I66017b200cd627bb9792f53ee39dd80d8e05965a

cmake/gmxDetectSimd.cmake
src/gromacs/simd/support.cpp

index 4231cb15eaaaa9b9289d227f58c6c9098f06fdb2..97d7f5b7ac239f6ebda6246999ec542dfd9f3187 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+# Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by
 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
 # and including many others, as listed in the AUTHORS file in the
 # top-level source directory and at http://www.gromacs.org.
@@ -95,8 +95,18 @@ function(gmx_suggest_simd _suggested_simd)
                 endif()
             elseif(CPU_DETECTION_FEATURES MATCHES " avx2 ")
                 if(CPU_DETECTION_FEATURES MATCHES " amd ")
-                    set(OUTPUT_SIMD "AVX2_128")
+                    gmx_run_cpu_detection(family)
+                    gmx_run_cpu_detection(model)
+                    set(ZEN1_MODELS 1 17 8 24)
+                    if("${CPU_DETECTION_FAMILY}" STREQUAL "23" AND "${CPU_DETECTION_MODEL}" IN_LIST ZEN1_MODELS)
+                        # Zen/Zen+, where 128-bit AVX2 will be faster
+                        set(OUTPUT_SIMD "AVX2_128")
+                    else()
+                        # Zen2 or later, where 256-bit AVX2 should be faster
+                        set(OUTPUT_SIMD "AVX2_256")
+                    endif()
                 else()
+                    # not AMD
                     set(OUTPUT_SIMD "AVX2_256")
                 endif()
             elseif(CPU_DETECTION_FEATURES MATCHES " avx ")
index d7b5839251d9ad3957d283aee2513ef9f92cdc17..d58c4286ffd8f451b4b3edb21c169ed11bea0e41 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -90,6 +90,30 @@ simdString(SimdType s)
     return name.at(s);
 }
 
+namespace
+{
+
+
+//! Helper to detect correct AMD Zen architecture.
+bool
+cpuIsAmdZen1(const CpuInfo &cpuInfo)
+{
+    // Both Zen/Zen+/Zen2 have family==23
+    // Model numbers for Zen:
+    // 1)  Naples, Whitehaven, Summit ridge, and Snowy Owl
+    // 17) Raven ridge
+    // Model numbers for Zen+:
+    // 8)  Pinnacle Ridge
+    // 24) Picasso
+    return (cpuInfo.vendor() == gmx::CpuInfo::Vendor::Amd &&
+            cpuInfo.family() == 23 &&
+            (cpuInfo.model() == 1 || cpuInfo.model() == 17 ||
+             cpuInfo.model() == 8 || cpuInfo.model() == 24) );
+}
+
+}   // namespace
+
+
 SimdType
 simdSuggested(const CpuInfo &c)
 {
@@ -129,10 +153,12 @@ simdSuggested(const CpuInfo &c)
             case CpuInfo::Vendor::Amd:
                 if (c.feature(CpuInfo::Feature::X86_Avx2))
                 {
-                    // AMD Ryzen supports 256-bit AVX2, but performs better with 128-bit
+                    // AMD Zen supports 256-bit AVX2, but Zen1 performs better with 128-bit
                     // since it can execute two independent such instructions per cycle,
                     // and wider SIMD has slightly lower efficiency in GROMACS.
-                    suggested = SimdType::X86_Avx2_128;
+                    // However... Zen2 supports full-width execution of 256-bit AVX2,
+                    // so we only want to apply this hack to Zen/Zen+.
+                    suggested = cpuIsAmdZen1(c) ? SimdType::X86_Avx2_128 : SimdType::X86_Avx2;
                 }
                 else if (c.feature(CpuInfo::Feature::X86_Avx))
                 {