aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Common/ThreadStaticPool.cs
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2021-02-22 03:23:48 +0100
committerGitHub <noreply@github.com>2021-02-22 03:23:48 +0100
commitdc0adb533dc15a007e9ca2dc0533ef6a61f13393 (patch)
tree4b3588600cfd163e9f7a72b176b15befe078e941 /ARMeilleure/Common/ThreadStaticPool.cs
parent15868801148129802173f2162ebff24835cb20ba (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.cs124
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;
}
}
}