[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