predict method of l4
This commit is contained in:
@@ -16,7 +16,6 @@ namespace Nitload.Common.HighPerformance.Memory
|
||||
public partial class L4
|
||||
{
|
||||
|
||||
private readonly IL4Predictor[] _ring = new IL4Predictor[256];
|
||||
private volatile int _consume;
|
||||
private volatile int _enter;
|
||||
private volatile int _predict;
|
||||
@@ -45,7 +44,8 @@ namespace Nitload.Common.HighPerformance.Memory
|
||||
if (ReferenceEquals(predictor, _ring[idx]))
|
||||
{
|
||||
int end = _predict;
|
||||
for (int move = i; move < end - 1; move++) {
|
||||
for (int move = i; move < end - 1; move++)
|
||||
{
|
||||
_ring[(byte)move] = _ring[(byte)(move + 1)];
|
||||
}
|
||||
_ring[(byte)(end - 1)] = default!;
|
||||
@@ -61,6 +61,12 @@ namespace Nitload.Common.HighPerformance.Memory
|
||||
}
|
||||
}
|
||||
|
||||
internal bool MoveNextPredictor()
|
||||
{
|
||||
int cur = Interlocked.Increment(ref _predict);
|
||||
return cur == _enter;
|
||||
}
|
||||
|
||||
internal void RegistPredictor(
|
||||
IL4Predictor predictor
|
||||
)
|
||||
@@ -69,18 +75,25 @@ namespace Nitload.Common.HighPerformance.Memory
|
||||
return;
|
||||
}
|
||||
SpinWait sp = new();
|
||||
|
||||
wait_for_spare:
|
||||
WaitForSpare();
|
||||
|
||||
while (Interlocked.CompareExchange(ref _queue_sync, 1, 0) != 0) {
|
||||
sp.SpinOnce();
|
||||
}
|
||||
if (_enter - _consume >= PredictorRingCapacity)
|
||||
{
|
||||
_ = Interlocked.Exchange(ref _queue_sync, 0);
|
||||
goto wait_for_spare;
|
||||
}
|
||||
|
||||
WaitForSpare();
|
||||
|
||||
_consume++;
|
||||
try
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
byte idx = (byte)_consume;
|
||||
_consume++;
|
||||
_ring[idx] = predictor;
|
||||
}
|
||||
}
|
||||
@@ -90,12 +103,28 @@ namespace Nitload.Common.HighPerformance.Memory
|
||||
}
|
||||
}
|
||||
|
||||
internal bool TryGetCurrentPredictor(
|
||||
out IL4Predictor predictor
|
||||
)
|
||||
{
|
||||
int cur = _predict;
|
||||
if (cur >= _enter)
|
||||
{
|
||||
predictor = default!;
|
||||
return false;
|
||||
}
|
||||
unchecked
|
||||
{
|
||||
predictor = _ring[(byte)cur];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void WaitForSpare()
|
||||
{
|
||||
int spin_count = 0;
|
||||
|
||||
// wait until the queue has space
|
||||
while (_enter - _consume >= 256)
|
||||
while (_enter - _consume >= PredictorRingCapacity)
|
||||
{
|
||||
switch (spin_count)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user