Improve memory safety and alignment handling
Some checks failed
Publish NuGet Packages / publish (pull_request) Failing after 1m5s
Some checks failed
Publish NuGet Packages / publish (pull_request) Failing after 1m5s
- Updated `.gitignore` to include `.vscode/` and clarified comments. - Introduced `SafeHandle` for managing memory alignment and safe access. - Refactored `UnsafeArray<T>` to add bounds checking and alignment logic. - Added `IUnsafeHashCollection<T>` for specialized hash-based collections. - Refactored `UnsafeHashMap<TKey, TValue>` and `UnsafeHashSet<T>` to use `HashMapHelper<TKey>` with alignment support. - Made `UnsafeSlotMap<T>` methods `readonly` for immutability. - Enhanced `HashMapHelper<TKey>` with alignment-aware buffer management and validation. - Updated benchmarks to use `UnsafeArray<Vector256<int>>` and added capacity checks. - Incremented assembly version to `1.1.3` in `Misaki.HighPerformance.LowLevel.csproj`. - Updated `Program.cs` to run `CollectionBenchmark` and demonstrate safe disposal handling.
This commit is contained in:
@@ -1,55 +1,49 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
using Misaki.HighPerformance.LowLevel.Collections;
|
||||
using System.Runtime.Intrinsics;
|
||||
|
||||
namespace Misaki.HighPerformance.Test.Benchmark;
|
||||
|
||||
[MemoryDiagnoser]
|
||||
public unsafe class CollectionBenchmark
|
||||
public class CollectionBenchmark
|
||||
{
|
||||
private UnsafeArray<Vector256<int>> _array;
|
||||
|
||||
[Params(10, 100, 1000)]
|
||||
public int count;
|
||||
|
||||
[GlobalSetup]
|
||||
public void Setup()
|
||||
{
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void Array()
|
||||
{
|
||||
var array = new int[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
array[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public void UnsafeArray()
|
||||
{
|
||||
var array = new UnsafeArray<int>(count, Allocator.Temp);
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
array[i] = i;
|
||||
}
|
||||
|
||||
AllocationManager.ResetTempAllocator();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void StackArray()
|
||||
{
|
||||
var array = stackalloc int[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
array[i] = i;
|
||||
}
|
||||
_array = new UnsafeArray<Vector256<int>>(count, Allocator.Persistent);
|
||||
}
|
||||
|
||||
[GlobalCleanup]
|
||||
public void Cleanup()
|
||||
{
|
||||
AllocationManager.Dispose();
|
||||
_array.Dispose();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void WithCapacityChecks()
|
||||
{
|
||||
for (var i = 0; i < _array.Count; i++)
|
||||
{
|
||||
if (i < 0 || i >= _array.Count)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
_array[i] = default;
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void WithoutCapacityChecks()
|
||||
{
|
||||
for (var i = 0; i < _array.Count; i++)
|
||||
{
|
||||
_array[i] = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,10 @@
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" />
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'" />
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.15.2" />
|
||||
<PackageReference Include="MSTest" Version="3.10.1" />
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
|
||||
//Console.WriteLine($"Count should be {threadCount * 990}, actual: {map.Count}");
|
||||
|
||||
//using Misaki.HighPerformance.Test.Benchmark;
|
||||
|
||||
BenchmarkDotNet.Running.BenchmarkRunner.Run<Misaki.HighPerformance.Test.Benchmark.MathematicsBenchmark>();
|
||||
BenchmarkDotNet.Running.BenchmarkRunner.Run<Misaki.HighPerformance.Test.Benchmark.CollectionBenchmark>();
|
||||
|
||||
//using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
//using Misaki.HighPerformance.LowLevel.Collections;
|
||||
@@ -40,3 +38,16 @@ BenchmarkDotNet.Running.BenchmarkRunner.Run<Misaki.HighPerformance.Test.Benchmar
|
||||
// }
|
||||
//}
|
||||
|
||||
//var arr1 = new Misaki.HighPerformance.LowLevel.Collections.UnsafeArray<int>(10, Misaki.HighPerformance.LowLevel.Buffer.Allocator.Persistent);
|
||||
//var arr2 = arr1;
|
||||
|
||||
//arr1.Dispose();
|
||||
//try
|
||||
//{
|
||||
// arr2[0] = 42; // This should throw an exception because arr1 has been disposed.
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// Console.WriteLine($"Caught expected exception: {ex.Message}");
|
||||
//}
|
||||
//arr2.Dispose(); // This should not cause a double free error because of safe handle.
|
||||
|
||||
Reference in New Issue
Block a user