From: Steve MacLean Date: Thu, 24 Aug 2017 17:54:37 +0000 (-0400) Subject: mscorlib cache padding for 128 byte lines (#13102) X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ad29b87442d8132f5c3a6fd3844e5e00989b2b47;p=platform%2Fupstream%2Fcoreclr.git mscorlib cache padding for 128 byte lines (#13102) * mscorlib ConcurrentQueue pad for 128B cache lines * Add Padding.cs --- diff --git a/src/mscorlib/System.Private.CoreLib.csproj b/src/mscorlib/System.Private.CoreLib.csproj index e7065d1bf2..609986876b 100644 --- a/src/mscorlib/System.Private.CoreLib.csproj +++ b/src/mscorlib/System.Private.CoreLib.csproj @@ -356,6 +356,7 @@ + @@ -678,4 +679,4 @@ $(IntermediateOutputPath)\System.Private.CoreLib.res - \ No newline at end of file + diff --git a/src/mscorlib/src/Internal/Padding.cs b/src/mscorlib/src/Internal/Padding.cs new file mode 100644 index 0000000000..d25acdc9c7 --- /dev/null +++ b/src/mscorlib/src/Internal/Padding.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +namespace Internal +{ + + /// A class for common padding constants and eventually routines. + internal static class PaddingHelpers + { + /// A size greater than or equal to the size of the most common CPU cache lines. +#if ARM64 + internal const int CACHE_LINE_SIZE = 128; +#else + internal const int CACHE_LINE_SIZE = 64; +#endif + } + + /// Padding structure used to minimize false sharing + [StructLayout(LayoutKind.Explicit, Size = PaddingHelpers.CACHE_LINE_SIZE - sizeof(int))] + internal struct PaddingFor32 + { + } +} + diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs index 632f0eecef..53b7525bc9 100644 --- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs +++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs @@ -1111,10 +1111,10 @@ namespace System.Collections.Concurrent /// Padded head and tail indices, to avoid false sharing between producers and consumers. [DebuggerDisplay("Head = {Head}, Tail = {Tail}")] - [StructLayout(LayoutKind.Explicit, Size = 192)] // padding before/between/after fields based on typical cache line size of 64 + [StructLayout(LayoutKind.Explicit, Size = 3*Internal.PaddingHelpers.CACHE_LINE_SIZE)] // padding before/between/after fields internal struct PaddedHeadAndTail { - [FieldOffset(64)] public int Head; - [FieldOffset(128)] public int Tail; + [FieldOffset(1*Internal.PaddingHelpers.CACHE_LINE_SIZE)] public int Head; + [FieldOffset(2*Internal.PaddingHelpers.CACHE_LINE_SIZE)] public int Tail; } } diff --git a/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs b/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs index f9d5f89398..df0dbe3942 100644 --- a/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs +++ b/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs @@ -332,7 +332,7 @@ namespace System.Threading.Tasks private struct SegmentState { /// Padding to reduce false sharing between the segment's array and m_first. - internal PaddingFor32 m_pad0; + internal Internal.PaddingFor32 m_pad0; /// The index of the current head in the segment. internal volatile int m_first; @@ -340,7 +340,7 @@ namespace System.Threading.Tasks internal int m_lastCopy; // not volatile as read and written by the producer, except for IsEmpty, and there m_lastCopy is only read after reading the volatile m_first /// Padding to reduce false sharing between the first and last. - internal PaddingFor32 m_pad1; + internal Internal.PaddingFor32 m_pad1; /// A copy of the current head index. internal int m_firstCopy; // not voliatle as only read and written by the consumer thread @@ -348,7 +348,7 @@ namespace System.Threading.Tasks internal volatile int m_last; /// Padding to reduce false sharing with the last and what's after the segment. - internal PaddingFor32 m_pad2; + internal Internal.PaddingFor32 m_pad2; } /// Debugger type proxy for a SingleProducerSingleConsumerQueue of T. @@ -366,17 +366,4 @@ namespace System.Threading.Tasks } } } - - /// A placeholder class for common padding constants and eventually routines. - internal static class PaddingHelpers - { - /// A size greater than or equal to the size of the most common CPU cache lines. - internal const int CACHE_LINE_SIZE = 128; - } - - /// Padding structure used to minimize false sharing in SingleProducerSingleConsumerQueue{T}. - [StructLayout(LayoutKind.Explicit, Size = PaddingHelpers.CACHE_LINE_SIZE - sizeof(Int32))] // Based on common case of 64-byte cache lines - internal struct PaddingFor32 - { - } } diff --git a/src/mscorlib/src/System/Threading/ThreadPool.cs b/src/mscorlib/src/System/Threading/ThreadPool.cs index e457f15eed..ec9ceef156 100644 --- a/src/mscorlib/src/System/Threading/ThreadPool.cs +++ b/src/mscorlib/src/System/Threading/ThreadPool.cs @@ -385,11 +385,11 @@ namespace System.Threading internal bool loggingEnabled; internal readonly ConcurrentQueue workItems = new ConcurrentQueue(); - private System.Threading.Tasks.PaddingFor32 pad1; + private Internal.PaddingFor32 pad1; private volatile int numOutstandingThreadRequests = 0; - private System.Threading.Tasks.PaddingFor32 pad2; + private Internal.PaddingFor32 pad2; public ThreadPoolWorkQueue() {