diff options
| author | LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> | 2021-02-22 03:23:48 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-22 03:23:48 +0100 |
| commit | dc0adb533dc15a007e9ca2dc0533ef6a61f13393 (patch) | |
| tree | 4b3588600cfd163e9f7a72b176b15befe078e941 /ARMeilleure/Common/ThreadStaticPool.cs | |
| parent | 15868801148129802173f2162ebff24835cb20ba (diff) | |
PPTC & Pool Enhancements. (#1968)
* PPTC & Pool Enhancements.
* Avoid buffer allocations in CodeGenContext.GetCode(). Avoid stream allocations in PTC.PtcInfo.
Refactoring/nits.
* Use XXHash128, for Ptc.Load & Ptc.Save, x10 faster than Md5.
* Why not a nice Span.
* Added a simple PtcFormatter library for deserialization/serialization, which does not require reflection, in use at PtcJumpTable and PtcProfiler; improves maintainability and simplicity/readability of affected code.
* Nits.
* Revert #1987.
* Revert "Revert #1987."
This reverts commit 998be765cf7f7da5ff0c1c08de704c9012b0f49c.
Diffstat (limited to 'ARMeilleure/Common/ThreadStaticPool.cs')
| -rw-r--r-- | ARMeilleure/Common/ThreadStaticPool.cs | 124 |
1 files changed, 101 insertions, 23 deletions
diff --git a/ARMeilleure/Common/ThreadStaticPool.cs b/ARMeilleure/Common/ThreadStaticPool.cs index e23bf1dc..bbe662f8 100644 --- a/ARMeilleure/Common/ThreadStaticPool.cs +++ b/ARMeilleure/Common/ThreadStaticPool.cs @@ -1,4 +1,5 @@ -using System; +using ARMeilleure.Translation.PTC; +using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -6,9 +7,6 @@ namespace ARMeilleure.Common { class ThreadStaticPool<T> where T : class, new() { - private const int ChunkSizeLimit = 1000; // even - private const int PoolSizeIncrement = 200; // > 0 - [ThreadStatic] private static ThreadStaticPool<T> _instance; @@ -18,21 +16,36 @@ namespace ARMeilleure.Common { if (_instance == null) { - PreparePool(0); // So that we can still use a pool when blindly initializing one. + PreparePool(); // So that we can still use a pool when blindly initializing one. } return _instance; } } - private static ConcurrentDictionary<int, Stack<ThreadStaticPool<T>>> _pools = new(); + private static readonly ConcurrentDictionary<int, Stack<ThreadStaticPool<T>>> _pools = new(); private static Stack<ThreadStaticPool<T>> GetPools(int groupId) { return _pools.GetOrAdd(groupId, (groupId) => new()); } - public static void PreparePool(int groupId) + public static void PreparePool( + int groupId = 0, + ChunkSizeLimit chunkSizeLimit = ChunkSizeLimit.Large, + PoolSizeIncrement poolSizeIncrement = PoolSizeIncrement.Default) + { + if (Ptc.State == PtcState.Disabled) + { + PreparePoolDefault(groupId, (int)chunkSizeLimit, (int)poolSizeIncrement); + } + else + { + PreparePoolSlim((int)chunkSizeLimit, (int)poolSizeIncrement); + } + } + + private static void PreparePoolDefault(int groupId, int chunkSizeLimit, int poolSizeIncrement) { // Prepare the pool for this thread, ideally using an existing one from the specified group. @@ -41,27 +54,75 @@ namespace ARMeilleure.Common var pools = GetPools(groupId); lock (pools) { - _instance = (pools.Count != 0) ? pools.Pop() : new(); + _instance = (pools.Count != 0) ? pools.Pop() : new(chunkSizeLimit, poolSizeIncrement); } } } - public static void ReturnPool(int groupId) + private static void PreparePoolSlim(int chunkSizeLimit, int poolSizeIncrement) + { + // Prepare the pool for this thread. + + if (_instance == null) + { + _instance = new(chunkSizeLimit, poolSizeIncrement); + } + } + + public static void ResetPool(int groupId = 0) + { + if (Ptc.State == PtcState.Disabled) + { + ResetPoolDefault(groupId); + } + else + { + ResetPoolSlim(); + } + } + + private static void ResetPoolDefault(int groupId) { // Reset, limit if necessary, and return the pool for this thread to the specified group. - var pools = GetPools(groupId); - lock (pools) + if (_instance != null) + { + var pools = GetPools(groupId); + lock (pools) + { + _instance.Clear(); + _instance.ChunkSizeLimiter(); + pools.Push(_instance); + + _instance = null; + } + } + } + + private static void ResetPoolSlim() + { + // Reset, limit if necessary, the pool for this thread. + + if (_instance != null) { _instance.Clear(); _instance.ChunkSizeLimiter(); - pools.Push(_instance); + } + } - _instance = null; + public static void DisposePools() + { + if (Ptc.State == PtcState.Disabled) + { + DisposePoolsDefault(); + } + else + { + DisposePoolSlim(); } } - public static void ResetPools() + private static void DisposePoolsDefault() { // Resets any static references to the pools used by threads for each group, allowing them to be garbage collected. @@ -78,20 +139,37 @@ namespace ARMeilleure.Common _pools.Clear(); } + private static void DisposePoolSlim() + { + // Dispose the pool for this thread. + + if (_instance != null) + { + _instance.Dispose(); + + _instance = null; + } + } + private List<T[]> _pool; private int _chunkIndex = -1; private int _poolIndex = -1; + private int _chunkSizeLimit; + private int _poolSizeIncrement; - private ThreadStaticPool() + private ThreadStaticPool(int chunkSizeLimit, int poolSizeIncrement) { - _pool = new(ChunkSizeLimit * 2); + _chunkSizeLimit = chunkSizeLimit; + _poolSizeIncrement = poolSizeIncrement; + + _pool = new(chunkSizeLimit * 2); AddChunkIfNeeded(); } public T Allocate() { - if (++_poolIndex >= PoolSizeIncrement) + if (++_poolIndex >= _poolSizeIncrement) { AddChunkIfNeeded(); @@ -105,9 +183,9 @@ namespace ARMeilleure.Common { if (++_chunkIndex >= _pool.Count) { - T[] pool = new T[PoolSizeIncrement]; + T[] pool = new T[_poolSizeIncrement]; - for (int i = 0; i < PoolSizeIncrement; i++) + for (int i = 0; i < _poolSizeIncrement; i++) { pool[i] = new T(); } @@ -124,18 +202,18 @@ namespace ARMeilleure.Common private void ChunkSizeLimiter() { - if (_pool.Count >= ChunkSizeLimit) + if (_pool.Count >= _chunkSizeLimit) { - int newChunkSize = ChunkSizeLimit / 2; + int newChunkSize = _chunkSizeLimit / 2; _pool.RemoveRange(newChunkSize, _pool.Count - newChunkSize); - _pool.Capacity = ChunkSizeLimit * 2; + _pool.Capacity = _chunkSizeLimit * 2; } } private void Dispose() { - _pool.Clear(); + _pool = null; } } } |
