HLSf use nuint rather than long, L4 now uses hlsf rather than array to alloc cache line.
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
// -----------------------------------------------------------------------
|
||||
// file="HLSFAllocator.SegmentEntry"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
// AuthorGroup: Nitload
|
||||
// Copyright (c) Nitload. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -29,7 +29,7 @@ using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace StgSharp.Mathematics.Memory
|
||||
namespace StgSharp.HighPerformance.Memory
|
||||
{
|
||||
public unsafe partial class HybridLayerSegregatedFitAllocator
|
||||
{
|
||||
@@ -38,37 +38,51 @@ namespace StgSharp.Mathematics.Memory
|
||||
/// Check if two Entries are adjacent in memory
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool AssertAdjacentTo(Entry* current, Entry* other)
|
||||
private static bool AssertAdjacentTo(
|
||||
Entry* current,
|
||||
Entry* other
|
||||
)
|
||||
{
|
||||
// Only a predicate; never throw here. Callers rely on false to skip merging.
|
||||
return other->Position + (nuint)other->Size == current->Position ||
|
||||
current->Position + (nuint)current->Size == other->Position;
|
||||
return (other->Position + other->Size == current->Position) ||
|
||||
(current->Position + current->Size == other->Position);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// check out if a bucket is within the same higher-level boundary as currentOffset
|
||||
/// </summary>
|
||||
private bool AssertBoundary(Entry* previous, Entry* current, int level)
|
||||
private bool AssertBoundary(
|
||||
Entry* previous,
|
||||
Entry* current,
|
||||
int level
|
||||
)
|
||||
{
|
||||
level = int.Min(level, MaxLevel);
|
||||
int nextLevelSize = _levelSizeArray[level] * 4;
|
||||
ulong prevHead = previous->Position - (ulong)m_Buffer,
|
||||
currHead = current->Position - (ulong)m_Buffer;
|
||||
return (currHead / (ulong)nextLevelSize) == (prevHead / (ulong)nextLevelSize);
|
||||
uint nextLevelSize = _levelSizeArray[level] * 4;
|
||||
ulong prevHead = previous->Position - ((ulong)m_Buffer),
|
||||
currHead = current->Position - ((ulong)m_Buffer);
|
||||
return currHead / nextLevelSize == prevHead / nextLevelSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine segment index based on size and originLevel
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int DetermineSegmentIndex(int[] levelSizeArray, long size, int level)
|
||||
private static int DetermineSegmentIndex(
|
||||
uint[] levelSizeArray,
|
||||
ulong size,
|
||||
int level
|
||||
)
|
||||
{
|
||||
level = int.Min(level, MaxLevel);
|
||||
return (int)((size - 1) / levelSizeArray[level]);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void InsertEntryAfter(Entry* entry, Entry* position)
|
||||
private static void InsertEntryAfter(
|
||||
Entry* entry,
|
||||
Entry* position
|
||||
)
|
||||
{
|
||||
Entry* next = position->NextNear;
|
||||
entry->NextNear = next;
|
||||
@@ -78,7 +92,10 @@ namespace StgSharp.Mathematics.Memory
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void InsertEntryBefore(Entry* entry, Entry* position)
|
||||
private static void InsertEntryBefore(
|
||||
Entry* entry,
|
||||
Entry* position
|
||||
)
|
||||
{
|
||||
Entry* prev = position->PreviousNear;
|
||||
entry->NextNear = position;
|
||||
@@ -92,24 +109,26 @@ namespace StgSharp.Mathematics.Memory
|
||||
/// Current Entry will serve as the final merged block. The Merge will be in lazy
|
||||
/// strategy.
|
||||
/// </summary>
|
||||
private void MergeAndRemoveFromBuckets(Entry* entry)
|
||||
private void MergeAndRemoveFromBuckets(
|
||||
Entry* entry
|
||||
)
|
||||
{
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
long size = entry->Size;
|
||||
nuint size = entry->Size;
|
||||
int originLevel = entry->Level;
|
||||
int segment = DetermineSegmentIndex(_levelSizeArray, size, originLevel);
|
||||
do
|
||||
{
|
||||
// previous direction merge
|
||||
Entry* p = entry->PreviousNear;
|
||||
if (p == null ||
|
||||
p == _spareMemory ||
|
||||
p->State != EntryState.Empty ||
|
||||
p->Level != entry->Level ||
|
||||
if ((p == null) ||
|
||||
(p == _spareMemory) ||
|
||||
(p->State != EntryState.Empty) ||
|
||||
(p->Level != entry->Level) ||
|
||||
!AssertBoundary(p, entry, originLevel))
|
||||
{
|
||||
break;
|
||||
@@ -126,10 +145,10 @@ namespace StgSharp.Mathematics.Memory
|
||||
{
|
||||
// next direction merge
|
||||
Entry* n = entry->NextNear;
|
||||
if (n == null ||
|
||||
n == _spareMemory ||
|
||||
n->State != EntryState.Empty ||
|
||||
n->Level != entry->Level ||
|
||||
if ((n == null) ||
|
||||
(n == _spareMemory) ||
|
||||
(n->State != EntryState.Empty) ||
|
||||
(n->Level != entry->Level) ||
|
||||
!AssertBoundary(n, entry, originLevel))
|
||||
{
|
||||
break;
|
||||
@@ -141,7 +160,7 @@ namespace StgSharp.Mathematics.Memory
|
||||
RemoveFromPositionChain(n);
|
||||
} while (true);
|
||||
originLevel = int.Min(9, originLevel);
|
||||
entry->Level += entry->Size >= _levelSizeArray[originLevel] * 4 ? 1 : 0;
|
||||
entry->Level += (entry->Size >= _levelSizeArray[originLevel] * 4) ? 1 : 0;
|
||||
entry->Level &= 15;
|
||||
|
||||
BucketNode* bucket = (BucketNode*)entry->Position;
|
||||
@@ -152,7 +171,9 @@ namespace StgSharp.Mathematics.Memory
|
||||
/// Remove node from position linked list, this method does not recycle a BucketNode from
|
||||
/// size bucket
|
||||
/// </summary>
|
||||
private void RemoveFromPositionChain(Entry* entry)
|
||||
private void RemoveFromPositionChain(
|
||||
Entry* entry
|
||||
)
|
||||
{
|
||||
Entry* prev = entry->PreviousNear;
|
||||
Entry* next = entry->NextNear;
|
||||
@@ -169,7 +190,11 @@ namespace StgSharp.Mathematics.Memory
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void SetEntryLevel(Entry* entry, nuint position, long size)
|
||||
private static void SetEntryLevel(
|
||||
Entry* entry,
|
||||
nuint position,
|
||||
nuint size
|
||||
)
|
||||
{
|
||||
entry ->Position = position;
|
||||
entry->Size = size;
|
||||
@@ -188,7 +213,7 @@ namespace StgSharp.Mathematics.Memory
|
||||
[FieldOffset(8)] internal Entry* PreviousNear; // Position linked list: previous pointer
|
||||
|
||||
[FieldOffset(24)] internal int Level; // Level of the block in the allocator
|
||||
[FieldOffset(16)] internal long Size; // Block size information
|
||||
[FieldOffset(16)] internal nuint Size; // Block size information
|
||||
[FieldOffset(36)] public EntryState State;
|
||||
[FieldOffset(28)] public nuint Position; // Memory block position
|
||||
|
||||
|
||||
Reference in New Issue
Block a user