get the benchmark result, very POWERFULL

This commit is contained in:
Youmu Liu
2026-01-29 20:05:53 +08:00
parent 29bee99355
commit 01984dee28
10 changed files with 125 additions and 42 deletions
+25 -6
View File
@@ -11,6 +11,7 @@ StgSharp provides both low-level and high-level bindings to OpenGL, multimedia c
## Core Modules
### StgSharp.Common
The main library containing core functionality:
- **Mathematics**: High-performance linear algebra, matrix operations, and mathematical utilities
@@ -22,6 +23,7 @@ The main library containing core functionality:
- **Environment**: Platform abstraction and system integration
### StgSharp.Script
General-purpose syntax analysis framework:
- **Syntax Analysis Framework**: Provides a flexible framework for parsing and analyzing various programming languages
@@ -31,6 +33,7 @@ General-purpose syntax analysis framework:
- **Grammar Parsing**: Extensible grammar parsing and validation system
### StgSharp.Model
Geometric model loading and interpretation:
- **Geometric Model Loading**: Responsible for loading and interpreting geometric models from various formats
@@ -40,6 +43,7 @@ Geometric model loading and interpretation:
- **Schema Validation**: Model structure validation and verification
### StgSharp.Native
Native library integration:
- **GLFW Integration**: Cross-platform window and input management
@@ -48,6 +52,7 @@ Native library integration:
- **Context Management**: Graphics context and resource management
### StgSharp.TerminalDialogue
Terminal-based user interface:
- **Interactive Terminal**: Command-line interface components
@@ -57,34 +62,48 @@ Terminal-based user interface:
## Key Features
### High-Performance Computing
- **Parallel Matrix Operations**: Multi-threaded matrix computations with optimized scheduling
- **SIMD Acceleration**: Hardware-optimized vector operations
- **Memory Management**: Custom allocators including HLSF (Hybrid Layer Segregated Fit)
- **Thread Pool Management**: Efficient task scheduling and execution
#### HLSF Benchmark Snapshot (BenchmarkDotNet)
Environment: Windows 11 (10.0.26100.7623), AMD Ryzen 7 6800H, .NET 8.0.23, x64 RyuJIT AVX2, GC = Concurrent Workstation.
| Method | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio |
|------- |-----:|-----:|------:|------:|-------:|----------:|-----------:|
| Hlsf | 838.4 µs | 16.67 µs | 40.58 µs | 1.00 | 0.12 | 64 B | 1.00 |
| Libc | 849.8 µs | 34.93 µs | 100.23 µs | 1.01 | 0.17 | 64 B | 1.00 |
```
This shows HLSF matching libc allocation throughput under the same workload. See the HLSF document for details and caveats.
BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.7623)
AMD Ryzen 7 6800H with Radeon Graphics, 1 CPU, 16 logical and 8 physical cores
.NET SDK 10.0.102
[Host] : .NET 8.0.23 (8.0.2325.60607), X64 RyuJIT AVX2
Toolchain=InProcessEmitToolchain InvocationCount=2048 UnrollFactor=1
```
| Method | Mean | Error | StdDev | Ratio | RatioSD |
|------- |-----:|-----:|------:|------:|-------:|
| Hlsf | 76.23 µs | 0.355 µs | 0.315 µs | 0.44 | 0.01 |
| Libc | 172.98 µs | 3.042 µs | 2.988 µs | 1.00 | 0.02 |
This run shows HLSF significantly faster than libc under the current configuration. See the HLSF document for details and caveats.
### Graphics and Rendering
- **OpenGL Integration**: Complete OpenGL API coverage
- **Cross-Platform Support**: Windows and Linux compatibility
- **Rendering Pipeline**: Flexible and extensible graphics framework
- **Shader Management**: Dynamic shader compilation and management
### Game Engine Capabilities
- **Entity System**: Flexible game object management
- **State Machine**: Game state and behavior management
- **Input Handling**: Comprehensive input and control systems
- **Resource Management**: Efficient asset loading and management
### Data Processing
- **STEP File Support**: Industrial data format processing
- **EXPRESS Language**: Domain-specific language compilation
- **Pipeline Processing**: Efficient data transformation workflows
+40 -25
View File
@@ -32,10 +32,12 @@ using System.Runtime.InteropServices;
namespace StgSharp.Benchmark
{
[MemoryDiagnoser]
[InvocationCount(16)]
[InvocationCount(2048)]
public class HlsfAllocatorBench
{
private const uint Alignment = 64;
private const int AllocationCount = 2048;
private static readonly int[] AllocSizes = [
@@ -55,7 +57,7 @@ namespace StgSharp.Benchmark
[GlobalCleanup]
public void Cleanup()
{
_hlsfAllocator.Dispose();
_hlsfAllocator?.Dispose();
_hlsfLocalList.Clear();
_hlsfLocalList.TrimExcess();
_libcLocalList.Clear();
@@ -65,27 +67,7 @@ namespace StgSharp.Benchmark
[Benchmark]
public void Hlsf()
{
for (int i = 0; i < AllocationCount; i++)
{
lock (_hlsfAllocator)
{
HybridLayerSegregatedFitAllocationHandle allocate = _hlsfAllocator.Alloc(GetNextRandomSize());
_hlsfLocalList.Add(allocate);
}
}
for (int i = 0; i < _hlsfLocalList.Count; i++)
{
lock (_hlsfAllocator) {
_hlsfAllocator.Free(_hlsfLocalList[i]);
}
}
}
public void InvocationSetup()
{
_hlsfLocalList.Clear();
_libcLocalList.Clear();
RunHlsf(_hlsfAllocator, FreePolicy.NoCollect);
}
[IterationSetup]
@@ -98,9 +80,15 @@ namespace StgSharp.Benchmark
[Benchmark(Baseline = true)]
public unsafe void Libc()
{
_libcLocalList.Clear();
for (int i = 0; i < AllocationCount; i++)
{
void* allocate = NativeMemory.AlignedAlloc(GetNextRandomSize(), 64);
uint size = AlignSize(GetNextRandomSize());
void* allocate = NativeMemory.AlignedAlloc(size, Alignment);
if (allocate == null) {
throw new OutOfMemoryException("NativeMemory.AlignedAlloc returned null.");
}
_libcLocalList.Add((nint)allocate);
}
@@ -113,7 +101,15 @@ namespace StgSharp.Benchmark
public void Setup()
{
_random = new Random(42);
_hlsfAllocator = new HybridLayerSegregatedFitAllocator(GetArenaBytes(), align:64);
_hlsfAllocator = new HybridLayerSegregatedFitAllocator(GetArenaBytes(), align:(int)Alignment);
}
private static uint AlignSize(
uint size
)
{
uint mask = Alignment - 1;
return (size + mask) & ~mask;
}
private static nuint GetArenaBytes()
@@ -134,5 +130,24 @@ namespace StgSharp.Benchmark
private uint GetNextRandomSize() => (uint)AllocSizes[_random.Next(AllocSizes.Length)];
private void RunHlsf(
HybridLayerSegregatedFitAllocator allocator,
FreePolicy policy
)
{
_hlsfLocalList.Clear();
for (int i = 0; i < AllocationCount; i++)
{
uint size = AlignSize(GetNextRandomSize());
HybridLayerSegregatedFitAllocationHandle allocate = allocator.Alloc(size);
_hlsfLocalList.Add(allocate);
}
for (int i = 0; i < _hlsfLocalList.Count; i++) {
allocator.Free(_hlsfLocalList[i], policy);
}
}
}
}
+8 -1
View File
@@ -25,7 +25,11 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
using StgSharp.Benchmark;
namespace StgSharp.Benchmark
@@ -37,7 +41,10 @@ namespace StgSharp.Benchmark
string[] args
)
{
BenchmarkRunner.Run<HlsfAllocatorBench>();
IConfig config = ManualConfig.Create(DefaultConfig.Instance)
.AddLogger(ConsoleLogger.Default)
.AddJob(Job.Default.WithToolchain(InProcessEmitToolchain.Instance));
BenchmarkRunner.Run<HlsfAllocatorBench>(config);
}
}
@@ -39,6 +39,15 @@ using hlsfHandle = StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAlloc
namespace StgSharp.HighPerformance.Memory
{
public enum FreePolicy
{
FullCollect,
LazyCollect,
NoCollect
}
public unsafe partial class HybridLayerSegregatedFitAllocator
{
@@ -79,9 +88,11 @@ namespace StgSharp.HighPerformance.Memory
/// </summary>
/// <param name="handle">
/// Handle to the allocated memory block
/// <param name="collectPolicy">
/// </param>
public void Free(
hlsfHandle handle
hlsfHandle handle,
FreePolicy collectPolicy = FreePolicy.NoCollect
)
{
Entry* e = handle.EntryHandle;
@@ -96,7 +107,10 @@ namespace StgSharp.HighPerformance.Memory
e->State = EntryState.Empty;
// Try merge with adjacent free blocks and remove them from buckets
if (collectPolicy == FreePolicy.LazyCollect)
{
MergeAndRemoveFromBuckets(e);
}
// Calculate final level and segment for the merged block
long finalSize = e->Size;
@@ -108,6 +122,10 @@ namespace StgSharp.HighPerformance.Memory
PushBucketToLevel(finalLevel, finalSegment, (BucketNode*)e->Position);
// Console.WriteLine("one block freed");
if (collectPolicy == FreePolicy.FullCollect)
{
Collect();
}
}
}
@@ -77,7 +77,7 @@ namespace StgSharp.HighPerformance.Memory
uint maxBlockSize
)
{
_entries = SlabAllocator<Entry>.Create(64, SlabBufferLayout.Chunked);
_entries = SlabAllocator<Entry>.Create(64, SlabBufferLayout.Chunked, false);
m_Buffer = (byte *)NativeMemory.AlignedAlloc(byteSize, (nuint)16);
_align = 16;
_size = byteSize;
@@ -111,7 +111,7 @@ namespace StgSharp.HighPerformance.Memory
throw new ArgumentException(
"Alignment must be a power of two and at least 16 bytes.");
}
_entries = SlabAllocator<Entry>.Create(64, SlabBufferLayout.Chunked);
_entries = SlabAllocator<Entry>.Create(64, SlabBufferLayout.Chunked, false);
m_Buffer = (byte *)NativeMemory.AlignedAlloc(byteSize, (nuint)align);
_align = align;
_size = byteSize;
@@ -138,7 +138,7 @@ namespace StgSharp.HighPerformance.Memory
throw new ArgumentException(
"Alignment must be a power of two and at least 16 bytes.");
}
_entries = SlabAllocator<Entry>.Create(64, SlabBufferLayout.Chunked);
_entries = SlabAllocator<Entry>.Create(64, SlabBufferLayout.Chunked, false);
m_Buffer = (byte *)NativeMemory.AlignedAlloc(byteSize, (nuint)align);
_align = align;
_size = byteSize;
@@ -38,6 +38,8 @@ namespace StgSharp.HighPerformance.Memory
internal sealed unsafe class ChunkedSlabAllocator<T> : SlabAllocator<T> where T : unmanaged
{
private bool _disposed;
private BufferStack<nuint> _buffers;
private BufferStack<nuint> _recycle;
private readonly int _elementSize = Unsafe.SizeOf<T>();
@@ -90,6 +92,10 @@ namespace StgSharp.HighPerformance.Memory
public override void Dispose()
{
if (_disposed) {
return;
}
_disposed = true;
// NativeMemory.Free((void*)_currentBuffer);
while (_buffers.TryPop(out nuint buffer))
{
@@ -97,6 +103,7 @@ namespace StgSharp.HighPerformance.Memory
}
_buffers.Dispose();
_recycle.Dispose();
GC.SuppressFinalize(this);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -41,6 +41,8 @@ namespace StgSharp.HighPerformance.Memory
internal sealed unsafe class ConcurrentChunkedSlabAllocator<T> : SlabAllocator<T> where T : unmanaged
{
private bool _disposed;
private readonly BufferExpansionLock _lock = new();
private ConcurrentBufferStack<nuint> _buffers;
private ConcurrentBufferStack<nuint> _recycle;
@@ -114,6 +116,10 @@ namespace StgSharp.HighPerformance.Memory
public override void Dispose()
{
if (_disposed) {
return;
}
_disposed = true;
NativeMemory.Free((void*)_currentBuffer);
while (_buffers.TryPop(out nuint buffer)) {
NativeMemory.Free((void*)buffer);
@@ -121,6 +127,7 @@ namespace StgSharp.HighPerformance.Memory
_lock.Dispose();
_buffers.Dispose();
_recycle.Dispose();
GC.SuppressFinalize(this);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -37,6 +37,8 @@ namespace StgSharp.HighPerformance.Memory
public sealed unsafe class ConcurrentSequentialSlabAllocator<T> : SlabAllocator<T> where T: unmanaged
{
private bool _disposed;
private T* _buffer;
private readonly BufferExpansionLock _lock = new();
@@ -120,9 +122,14 @@ namespace StgSharp.HighPerformance.Memory
public override void Dispose()
{
if (_disposed) {
return;
}
_disposed = true;
_stack.Dispose();
NativeMemory.Free(_buffer);
_lock.Dispose();
GC.SuppressFinalize(this);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+4 -4
View File
@@ -51,10 +51,10 @@ DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, sse, , fma)
c3 = _mm_add_ps(c3, _mm_mul_ps(a2, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(2))));
c3 = _mm_add_ps(c3, _mm_mul_ps(a3, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(3))));
ans->f32_x[0] = c0;
ans->f32_x[1] = c1;
ans->f32_x[2] = c2;
ans->f32_x[3] = c3;
_mm_store_ps((float *)&ans->f32_x[0], c0);
_mm_store_ps((float *)&ans->f32_x[1], c1);
_mm_store_ps((float *)&ans->f32_x[2], c2);
_mm_store_ps((float *)&ans->f32_x[3], c3);
}
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, avx, , fma)
+4 -1
View File
@@ -49,7 +49,10 @@ namespace StgSharp
.UseModule<NumericalModule>()
.UseModule<GraphicModule>()
.InitializeModule();
TestMatrix();
HlsfStressTest.Run();
// TestMatrix();
// --- Logarithmic time sequence test: print seconds at each emitted span ---