From a37c9fcc51225fdbdfa6644534f79ad7ec1715e6 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Mon, 19 Jul 2021 15:53:55 -0400 Subject: [PATCH 1/2] Fix % used in PerCoreLockedStacks s_lockedStackCount will be a const in tier 1, and the JIT can optimize % by a const to something other than idiv. --- .../src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs index 3f75953261426..090bd3680397f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs @@ -281,7 +281,7 @@ public bool TryPush(T[] array) // Try to push on to the associated stack first. If that fails, // round-robin through the other stacks. LockedStack[] stacks = _perCoreStacks; - int index = Thread.GetCurrentProcessorId() % stacks.Length; + int index = Thread.GetCurrentProcessorId() % s_lockedStackCount; // mod by constant in tier 1 for (int i = 0; i < stacks.Length; i++) { if (stacks[index].TryPush(array)) return true; @@ -298,7 +298,7 @@ public bool TryPush(T[] array) // Try to pop from the associated stack first. If that fails, round-robin through the other stacks. T[]? arr; LockedStack[] stacks = _perCoreStacks; - int index = Thread.GetCurrentProcessorId() % s_lockedStackCount; // when ProcessorCount is a power of two, the JIT can optimize this in tier 1 + int index = Thread.GetCurrentProcessorId() % s_lockedStackCount; // mod by constant in tier 1 for (int i = 0; i < stacks.Length; i++) { if ((arr = stacks[index].TryPop()) is not null) return arr; From e1976735a52dff9edb0f1b130faf8f83b7733b8f Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Mon, 19 Jul 2021 22:41:55 -0400 Subject: [PATCH 2/2] Address PR feedback --- .../src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs index 090bd3680397f..fd4d242463c32 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs @@ -281,7 +281,7 @@ public bool TryPush(T[] array) // Try to push on to the associated stack first. If that fails, // round-robin through the other stacks. LockedStack[] stacks = _perCoreStacks; - int index = Thread.GetCurrentProcessorId() % s_lockedStackCount; // mod by constant in tier 1 + int index = (int)((uint)Thread.GetCurrentProcessorId() % (uint)s_lockedStackCount); // mod by constant in tier 1 for (int i = 0; i < stacks.Length; i++) { if (stacks[index].TryPush(array)) return true; @@ -298,7 +298,7 @@ public bool TryPush(T[] array) // Try to pop from the associated stack first. If that fails, round-robin through the other stacks. T[]? arr; LockedStack[] stacks = _perCoreStacks; - int index = Thread.GetCurrentProcessorId() % s_lockedStackCount; // mod by constant in tier 1 + int index = (int)((uint)Thread.GetCurrentProcessorId() % (uint)s_lockedStackCount); // mod by constant in tier 1 for (int i = 0; i < stacks.Length; i++) { if ((arr = stacks[index].TryPop()) is not null) return arr;