[commit: ghc] master: Fix NUMA support on Windows (#15049) (75361b1)

git at git.haskell.org git at git.haskell.org
Thu May 3 19:02:27 UTC 2018


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/75361b119c609f0ab98f3d12a15690aae4ce42a1/ghc

>---------------------------------------------------------------

commit 75361b119c609f0ab98f3d12a15690aae4ce42a1
Author: David Kraeutmann <kane at kane.cx>
Date:   Thu May 3 12:36:34 2018 -0400

    Fix NUMA support on Windows (#15049)
    
    * osNumaNodes now returns the right number of nodes
    * thread affinity is now correctly set
    
    TODO: no noticeable performance improvement.
    does windows already distribute threads in a NUMA-aware fashion?
    
    Test Plan:
    * validate
    * local tests on a NUMA machine
    
    Reviewers: bgamari, erikd, simonmar
    
    Reviewed By: bgamari, simonmar
    
    Subscribers: thomie, carter
    
    Differential Revision: https://phabricator.haskell.org/D4607


>---------------------------------------------------------------

75361b119c609f0ab98f3d12a15690aae4ce42a1
 rts/win32/OSMem.c     | 23 ++++++++++++++++-------
 rts/win32/OSThreads.c |  3 +--
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/rts/win32/OSMem.c b/rts/win32/OSMem.c
index 534cd15..d05151c 100644
--- a/rts/win32/OSMem.c
+++ b/rts/win32/OSMem.c
@@ -510,9 +510,18 @@ uint32_t osNumaNodes(void)
     static ULONG numNumaNodes = 0;
 
     /* Cache the amount of NUMA nodes. */
-    if (!numNumaNodes && !GetNumaHighestNodeNumber(&numNumaNodes))
+    if (!numNumaNodes)
     {
-        numNumaNodes = 1;
+        if (GetNumaHighestNodeNumber(&numNumaNodes))
+        {
+            // GetNumaHighestNodeNumber returns the highest node number
+            // i.e: 0 for a non-NUMA system, and >0 for a NUMA system, so add a 1.
+            numNumaNodes += 1;
+        }
+        else
+        {
+            numNumaNodes = 1;
+        }
     }
 
     return numNumaNodes;
@@ -520,12 +529,12 @@ uint32_t osNumaNodes(void)
 
 uint64_t osNumaMask(void)
 {
-    uint64_t numaMask;
-    if (!GetNumaNodeProcessorMask(0, &numaMask))
-    {
-        return 1;
+    // the concept of a numa node mask (c.f. numa_get_mems_allowed on POSIX)
+    // doesn't exist on Windows. Thus, all nodes are allowed.
+    if (osNumaNodes() > sizeof(StgWord)*8) {
+        barf("osNumaMask: too many NUMA nodes (%d)", osNumaNodes());
     }
-    return numaMask;
+    return (1 << osNumaNodes()) - 1;
 }
 
 void osBindMBlocksToNode(
diff --git a/rts/win32/OSThreads.c b/rts/win32/OSThreads.c
index b1a98ce..cc67353 100644
--- a/rts/win32/OSThreads.c
+++ b/rts/win32/OSThreads.c
@@ -579,8 +579,7 @@ void setThreadNode (uint32_t node)
     if (osNumaAvailable())
     {
         StgWord mask = 0;
-        mask |= 1 << node;
-        if (!SetThreadAffinityMask(GetCurrentThread(), mask))
+        if (!GetNumaNodeProcessorMask(node, &mask) && !SetThreadAffinityMask(GetCurrentThread(), mask))
         {
             sysErrorBelch(
                 "setThreadNode: Error setting affinity of thread to NUMA node `%u': %lu.",



More information about the ghc-commits mailing list