diff --git a/StgSharp.Common/HighPerformance/M128.cs b/StgSharp.Common/HighPerformance/M128.cs index f25ec59a..ecc62cec 100644 --- a/StgSharp.Common/HighPerformance/M128.cs +++ b/StgSharp.Common/HighPerformance/M128.cs @@ -50,9 +50,16 @@ namespace StgSharp.HighPerformance internal M128(Vector4 v) { + Unsafe.SkipInit(out this); Vec = v.AsVector128(); } + internal M128(Vector128 v) + { + Unsafe.SkipInit(out this); + Vec = v; + } + public ref T AsRef() where T: unmanaged, INumber { return ref Unsafe.As(ref Buffer[0]); diff --git a/StgSharp.Common/HighPerformance/MatrixKernel.cs b/StgSharp.Common/HighPerformance/MatrixKernel.cs index a16791e5..edc688b2 100644 --- a/StgSharp.Common/HighPerformance/MatrixKernel.cs +++ b/StgSharp.Common/HighPerformance/MatrixKernel.cs @@ -61,6 +61,26 @@ namespace StgSharp.HighPerformance Unsafe.SkipInit(out this); } + public MatrixKernel(bool clear) + { + if (!clear) { + Unsafe.SkipInit(out this); + } + } + + public static MatrixKernel Fp32Unit + { + get + { + MatrixKernel kernel = new(true); + kernel.FP32Buffer[0] = 1f; + kernel.FP32Buffer[3] = 1f; + kernel.FP32Buffer[8] = 1f; + kernel.FP32Buffer[15] = 1f; + return kernel; + } + } + public ref T UnsafeIndex(int column, int row) where T: unmanaged, INumber { ref M128 col = ref Unsafe.As(ref Buffer[0]); diff --git a/StgSharp.Common/HighPerformance/UnmanagedMemoryHandle.cs b/StgSharp.Common/HighPerformance/UnmanagedMemoryHandle.cs deleted file mode 100644 index 874bb231..00000000 --- a/StgSharp.Common/HighPerformance/UnmanagedMemoryHandle.cs +++ /dev/null @@ -1,62 +0,0 @@ -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- -// file="UnmanagedMemoryHandle.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. 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 in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- -using System; -using System.Buffers; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.HighPerformance -{ - public ref struct UnmanagedMemoryHandle - { - - public nuint Postion; - public Span Buffer; - - public UnmanagedMemoryHandle() { } - - public ref byte this[int index] - { -[MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref Buffer[index]; - } - - public Span.Enumerator GetEnumerator() - { - return Buffer.GetEnumerator(); - } - - } -} diff --git a/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.IndexNode.cs b/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.IndexNode.cs deleted file mode 100644 index d2e1c8c4..00000000 --- a/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.IndexNode.cs +++ /dev/null @@ -1,144 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="UnmanagedMemoryPool.IndexNode.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. 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 in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection.Emit; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.HighPerformance -{ - public unsafe partial class UnmanagedMemoryPool - { - - private const int - LevelOf4096 = 4, - LevelOf1024 = 3, - LevelOf256 = 2, - LevelOf64 = 1; - - internal readonly ref struct NextIndexNode - { - - private readonly Span _layout; - - public readonly nuint this[int level] - { -[MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Position - _layout[level].Member(0); -[MethodImpl(MethodImplOptions.AggressiveInlining)] - set => _layout[level].Member(0) = (uint)(Position - value); - } - - private readonly ref nuint Position - { -[MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref _layout[0].Member(0); - } - - } - - internal readonly ref struct PreviousIndexNode - { - - private readonly Span _layout; - - public readonly nuint this[int level] - { -[MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Position - _layout[level].Member(1); -[MethodImpl(MethodImplOptions.AggressiveInlining)] - set => _layout[level].Member(1) = (uint)(Position - value); - } - - private readonly ref nuint Position - { -[MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref _layout[0].Member(0); - } - - } - - [StructLayout(LayoutKind.Explicit)] - internal readonly ref struct IndexNode - { - - private static readonly uint[] _sizeArr = [16, 64, 256, 1024, 4096]; - [FieldOffset(0)] private readonly NextIndexNode nxt; - [FieldOffset(0)] private readonly PreviousIndexNode pre; - [FieldOffset(0)] private readonly Span _layout; - - public IndexNode(ref byte span) - { - _layout = MemoryMarshal.CreateSpan(ref Unsafe.As(ref span), 8); - } - - public readonly ref nuint Position => ref _layout[0].Member(0); - - public readonly ref uint Size => ref _layout[5].Member(0); - - public readonly ref int Level => ref _layout[5].Member(1); - - public readonly ref nuint Segment => ref _layout[6].Member(0); - - public readonly uint BlockSize => LevelToSize(Level); - - public static uint LevelToSize(int level) - { - return level switch - { - < 0 or > 4 => throw new ArgumentOutOfRangeException( - nameof(level), "Level must be from 1 to 4."), - _ => _sizeArr[level] - }; - } - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - public readonly ref readonly NextIndexNode Next - { -[MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref nxt; - } - - public readonly ref readonly PreviousIndexNode Previous - { -[MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref pre; - } -#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - } - - } -} diff --git a/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.IndexOperation.cs b/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.IndexOperation.cs deleted file mode 100644 index 9f86efa5..00000000 --- a/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.IndexOperation.cs +++ /dev/null @@ -1,187 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="UnmanagedMemoryPool.IndexOperation.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. 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 in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System.Runtime.CompilerServices; - -namespace StgSharp.HighPerformance -{ - public unsafe partial class UnmanagedMemoryPool - { - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConnectToNodeAtLevel( - IndexNode previous, - IndexNode current, - int level, - bool isHead) - { - if (isHead) - { - _entrance[level] = current.Position; - current.Previous[level] = 0; - } else - { - previous.Next[level] = current.Previous[level] = (uint)(current.Position - previous.Position); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private IndexNode GetNode(nuint pos) - { - ref byte span = ref *(_buffer + pos); - IndexNode node = new(ref span) - { - Position = pos - }; - return node; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool IsNodeBeginning(nuint pos, int level) - { - return _entrance[level] == pos; - } - - private bool Rebase(IndexNode n, uint offset) - { - nuint pos = n.Position; - uint size = n.Size; - if (size <= offset + 64) - { - for (int i = 0; i <= n.Level; i++) { - RemoveLevelHead(n, i); - } - return false; - } - uint - newOffset = ((offset / 64) + 1) * 64, - remain = n.Size - newOffset, - c64 = remain % 4, - c256 = remain / 4, - c1024 = c256 / 4, - c4096 = c1024 / 4; - c256 %= 4; - c1024 %= 4; - IndexNode - /* - * level is not important here, higher level will get 0 Size, - * and ignored in coming logic - */ - p64 = GetNode(n.Position - n.Previous[1]), - p256 = GetNode(n.Position - n.Previous[2]), - p1024 = GetNode(n.Position - n.Previous[3]), - p4096 = GetNode(n.Position - n.Previous[4]), - n64 = GetNode(n.Position + n.Previous[1]), - n256 = GetNode(n.Position + n.Previous[2]), - n1024 = GetNode(n.Position + n.Previous[3]), - n4096 = GetNode(n.Position + n.Previous[4]); - IndexNode nTemp; - if (c64 != 0) - { - // set param to separated 64 bytes block and set next and previous offset to it. - size = c64 * 64; - pos += size; - nTemp = GetNode(pos); - nTemp.Position = pos; - nTemp.Size = size; - ConnectToNodeAtLevel(p64, nTemp, 1, n.Position == _entrance[1]); - p64 = nTemp; - } - if (c256 != 0) - { - size = c256 * 256; - pos += size; - nTemp = GetNode(pos); - nTemp.Position = pos; - nTemp.Size = size; - nTemp.Previous[2] = n.Previous[2] + size; - ConnectToNodeAtLevel(p64, nTemp, 1, p64.Position == _entrance[1]); - ConnectToNodeAtLevel(p256, nTemp, 2, n.Position == _entrance[2]); - p64 = p256 = nTemp; - } - if (c1024 != 0) - { - size = c1024 * 1024; - pos += size; - nTemp = GetNode(pos); - nTemp.Position = pos; - nTemp.Size = size; - nTemp.Previous[2] = n.Previous[2] + size; - - // connect to previous node - ConnectToNodeAtLevel(p64, nTemp, 1, p64.Position == _entrance[1]); - ConnectToNodeAtLevel(p256, nTemp, 2, p256.Position == _entrance[2]); - ConnectToNodeAtLevel(p1024, nTemp, 3, n.Position == _entrance[3]); - p64 = p256 = p1024 = nTemp; - } - if (c4096 != 0) - { - size = c1024 * 1024; - pos += size; - nTemp = GetNode(pos); - nTemp.Position = pos; - nTemp.Size = size; - nTemp.Previous[2] = n.Previous[2] + size; - - // connect to previous node - ConnectToNodeAtLevel(p64, nTemp, 1, p64.Position == _entrance[1]); - ConnectToNodeAtLevel(p256, nTemp, 2, p256.Position == _entrance[2]); - ConnectToNodeAtLevel(p1024, nTemp, 3, p1024.Position == _entrance[3]); - ConnectToNodeAtLevel(p4096, nTemp, 4, n.Position == _entrance[4]); - p64 = p256 = p1024 = p4096 = nTemp; - } - - ConnectToNodeAtLevel(p64, n64, 1, false); - ConnectToNodeAtLevel( - p256, n256, 2, _entrance[2] == n.Position && n256.Position == n.Position); - ConnectToNodeAtLevel( - p1024, n1024, 3, _entrance[3] == n.Position && n1024.Position == n.Position); - ConnectToNodeAtLevel( - p4096, n4096, 4, _entrance[4] == n.Position && n4096.Position == n.Position); - return true; - } - - private void RemoveLevelHead(IndexNode n, int level) - { - IndexNode nxt, pre; - if (n.Previous[level] == 0) - { - // head of usable LEVEL; - nxt = GetNode(n.Position + n.Next[level]); - _entrance[level] = nxt.Position; - } - pre = GetNode(n.Previous[level]); - nxt = GetNode(n.Next[level]); - nxt.Previous[level] = nxt.Previous[level] + n.Previous[level]; - pre.Next[level] = pre.Next[level] + n.Next[level]; - } - - } -} diff --git a/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.MegaManage.cs b/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.MegaManage.cs deleted file mode 100644 index 665cd324..00000000 --- a/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.MegaManage.cs +++ /dev/null @@ -1,156 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="UnmanagedMemoryPool.MegaManage.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. 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 in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System.Collections.Generic; -using System.Runtime.CompilerServices; - -namespace StgSharp.HighPerformance -{ - public unsafe partial class UnmanagedMemoryPool - { - - private readonly LinkedList _megaAlloc = new(); - - private readonly LinkedList _megaEmpty = new(); - private MegaBlockHead _megaFirst; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void InsertMegaNear(MegaBlockHead previous, MegaBlockHead current) - { - MegaBlockHead pp = current.PreviousNear; - pp.NextNear = previous; - previous.PreviousNear = pp; - previous.NextNear = current; - current.PreviousNear = previous; - } - - private static void InsertMegaSorted(LinkedList list, MegaBlockHead newItem) - { - LinkedListNode? node = list.First; - - while (node != null && node.Value.Position < newItem.Position) { - node = node.Next; - } - - _ = node != null ? list.AddBefore(node, newItem) : list.AddLast(newItem); - } - - private bool TryGetMegaBlock(nuint size, out nuint position, int align = 1) - { - LinkedListNode node = _megaEmpty.First!; - while (node is not null) - { - MegaBlockHead block = node.Value; - if (block.Size >= size + (nuint)align) - { - position = block.Position; - nuint s = position + (nuint)(align - 1); - MegaBlockHead b; - if (block.Rebase(s)) - { - b = new() - { - Position = position, - Size = position + (nuint)(align - 1), - Usage = MegaBlockUsage.MegaAlloc, - }; - InsertMegaSorted(_megaAlloc, b); - InsertMegaNear(b, block); - } else - { - b = new() - { - Position = position, - Size = block.Size, - Usage = MegaBlockUsage.MegaAlloc, - }; - InsertMegaSorted(_megaAlloc, b); - _megaEmpty.Remove(node); - InsertMegaNear(b, block.NextNear); - } - position = s & (nuint)~(align - 1); - return true; - } - node = node.Next!; - } - position = 0; - return false; - } - - private unsafe class MegaBlockHead - { - - private readonly ulong[] Heads = new ulong[4]; - - public MegaBlockHead NextNear { get; set; } - - public MegaBlockHead PreviousNear { get; set; } - - public MegaBlockUsage Usage { get; set; } - - public nuint Position { get; set; } - - public nuint Size { get; set; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref nuint DagHead(int level) - { - return ref Unsafe.As(ref Heads[level]); - } - - public bool Rebase(nuint size) - { - nuint s = this.Size - size; - if (s > 1024 * 1024 * 128)//space larger than 128MB is considered a new mega block - { - Position += size; - this.Size -= size; - Usage = MegaBlockUsage.EmptyDag; - return true; - } - MegaBlockHead pre = PreviousNear, nxt = NextNear; - pre.NextNear = nxt; - nxt.PreviousNear = pre; - return false; - } - - } - - private enum MegaBlockUsage - { - - EmptyDag = 0, - UsedDag = 1, - MegaAlloc = 2 - - } - - } -} diff --git a/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.cs b/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.cs deleted file mode 100644 index 14abc6db..00000000 --- a/StgSharp.Common/HighPerformance/UnmanagedMemoryPool.cs +++ /dev/null @@ -1,171 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="UnmanagedMemoryPool.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. 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 in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Collections.Concurrent; -using System.Net.Security; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Threading; -using System.Transactions; - -namespace StgSharp.HighPerformance -{ - public unsafe partial class UnmanagedMemoryPool - { - - private readonly byte* _buffer; - - // 4k,1k,256b,64b,16b - private nuint[] _entrance = new nuint[5]; - private bool _disposedValue; - private readonly nuint _initialCapacity; - - internal UnmanagedMemoryPool(nuint initialCapacity, int memoryAlign) - { - _initialCapacity = initialCapacity; - _buffer = (byte*)NativeMemory.AlignedAlloc(initialCapacity, (nuint)memoryAlign); - } - - public UnmanagedMemoryHandle Allocate(uint size = 0) - { - if (size == 0) { - return new UnmanagedMemoryHandle - { - Postion = 0, - Buffer = new Span(_buffer, 0) - }; - } - if (size > 0x8000_0000) { - throw new ArgumentOutOfRangeException( - "Size of buffer cannot be greater than 2147483648"); - } - int level = GetLevelFromSize(size); - IndexNode allocator = GetNode(_entrance[level]); - nuint previous = allocator.Previous[level]; - if (allocator.Size < size) - { - previous = allocator.Position; - allocator = GetNode(allocator.Next[level]); - } - bool isOverflow = false; - checked - { - try - { - isOverflow = (uint)(allocator.Position - previous + size) > 0xC0000000; - } - catch (OverflowException) - { - isOverflow = true; - } - } - if (isOverflow) - { - // offset is too large - } - - UnmanagedMemoryHandle handle = new() - { - Postion = allocator.Position, - Buffer = new Span(_buffer + allocator.Position, (int)size), - }; - Rebase(allocator, size); - return handle; - } - - public static UnmanagedMemoryPool Create(nuint initialCapacity, int memoryAlign = 16) - { - UnmanagedMemoryPool pool = new(initialCapacity, memoryAlign); - IndexNode node = pool.GetNode(0); - for (int i = 4; i > 0; i--) - { - node.Previous[i] = 0; - node.Next[i] = IndexNode.LevelToSize(i); - } - node.Size = (uint)initialCapacity; - pool._megaFirst = new MegaBlockHead - { - Position = 0, - Size = initialCapacity, - Usage = MegaBlockUsage.EmptyDag - }; - _ = pool._megaEmpty.AddLast(pool._megaFirst); - return pool; - } - - public void Dispose() - { - Dispose(disposing:true); - GC.SuppressFinalize(this); - } - - public void Free(UnmanagedMemoryHandle handle) - { - if (_buffer + handle.Postion != Unsafe.AsPointer(ref handle.Buffer[0])) { - throw new InvalidOperationException("Handle does not belong to pool"); - } - nuint location = handle.Postion; - IndexNode root = GetNode(_entrance[4]); - while (root.Position > location) { } - } - - protected virtual void Dispose(bool disposing) - { - if (!_disposedValue) - { - if (disposing) { } - - NativeMemory.AlignedFree(_buffer); - _entrance = null!; - _disposedValue = true; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private int GetLevelFromSize(uint size) - { - int level = 0; - uint temp = size / 8; - while (temp > 3) - { - level++; - temp >>= 2; - } - return level; - } - - ~UnmanagedMemoryPool() - { - Dispose(disposing:false); - } - - } -} diff --git a/StgSharp.Common/Internal/Intrinsic/IntrinsicContext.cs b/StgSharp.Common/Internal/Intrinsic/IntrinsicContext.cs index 6fa6f251..dfb30aac 100644 --- a/StgSharp.Common/Internal/Intrinsic/IntrinsicContext.cs +++ b/StgSharp.Common/Internal/Intrinsic/IntrinsicContext.cs @@ -1,33 +1,33 @@ //----------------------------------------------------------------------- -//----------------------------------------------------------------------- -// file="IntrinsicContext.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// ----------------------------------------------------------------------- +// file="IntrinsicContext.cs" +// Project: StgSharp +// AuthorGroup: Nitload Space +// Copyright (c) Nitload Space. 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 in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: // -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. +// The above copyright notice and +// this permission notice shall be included in all copies +// or substantial portions of the Software. // -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// THE SOFTWARE IS PROVIDED “AS IS”, +// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- using StgSharp; using StgSharp.HighPerformance; using System; @@ -41,7 +41,7 @@ using System.Threading.Tasks; namespace StgSharp.Internal.Intrinsic { - [StructLayout( LayoutKind.Sequential )] + [StructLayout(LayoutKind.Sequential)] internal unsafe struct IntrinsicContext { @@ -57,6 +57,7 @@ namespace StgSharp.Internal.Intrinsic public delegate* unmanaged[Cdecl] dot_42; public delegate* unmanaged[Cdecl] dot_43; public delegate* unmanaged[Cdecl] factorial_simd; + public delegate* unmanaged[Cdecl] fma_44; public delegate* unmanaged[Cdecl] index_pair; public delegate* unmanaged[Cdecl] normalize_v3; public delegate* unmanaged[Cdecl] sub_mat_2; diff --git a/StgSharp.Common/Internal/Intrinsic/intrinsicContextProvider.cs b/StgSharp.Common/Internal/Intrinsic/intrinsicContextProvider.cs index ee4729c3..516f03df 100644 --- a/StgSharp.Common/Internal/Intrinsic/intrinsicContextProvider.cs +++ b/StgSharp.Common/Internal/Intrinsic/intrinsicContextProvider.cs @@ -1,33 +1,33 @@ //----------------------------------------------------------------------- -//----------------------------------------------------------------------- -// file="intrinsicContextProvider.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// ----------------------------------------------------------------------- +// file="intrinsicContextProvider.cs" +// Project: StgSharp +// AuthorGroup: Nitload Space +// Copyright (c) Nitload Space. 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 in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the ¡°Software¡±), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: // -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. +// The above copyright notice and +// this permission notice shall be included in all copies +// or substantial portions of the Software. // -// THE SOFTWARE IS PROVIDED ¡°AS IS¡±, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// THE SOFTWARE IS PROVIDED ¡°AS IS¡±, +// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- using StgSharp.Internal.Intrinsic; using System; @@ -44,6 +44,7 @@ namespace StgSharp.Internal internal static IntrinsicContext Intrinsic { +[MethodImpl(MethodImplOptions.AggressiveInlining)] get => _intrinsicContext; } @@ -51,25 +52,25 @@ namespace StgSharp.Internal { int statCode; - fixed( IntrinsicContext* cptr = &_intrinsicContext ) { - statCode = LoadIntrinsicFunction( cptr ); + fixed (IntrinsicContext* cPtr = &_intrinsicContext) { + statCode = LoadIntrinsicFunction(cPtr); } - switch( statCode ) + switch (statCode) { case 0: - //Dialogue.PostError(new PlatformNotSupportedException("No SIMD instructions supported on current hardware platform")); - Environment.Exit( -1 ); + // Dialogue.PostError(new PlatformNotSupportedException("No SIMD instructions supported on current hardware platform")); + Environment.Exit(-1); break; default: break; } } - [LibraryImport( NativeLibName, EntryPoint = "load_intrinsic_function" )] - [UnmanagedCallConv( CallConvs = [typeof( CallConvCdecl )] )] - private static partial int LoadIntrinsicFunction( IntrinsicContext* context ); + [LibraryImport(NativeLibName, EntryPoint = "load_intrinsic_function")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + private static partial int LoadIntrinsicFunction(IntrinsicContext* context); } } \ No newline at end of file diff --git a/StgSharp.Common/Mathematics/Graphic/Camera.cs b/StgSharp.Common/Mathematics/Graphic/Camera.cs index 748df223..5f86e3ed 100644 --- a/StgSharp.Common/Mathematics/Graphic/Camera.cs +++ b/StgSharp.Common/Mathematics/Graphic/Camera.cs @@ -31,6 +31,7 @@ using StgSharp.Graphics; using StgSharp.Graphics.OpenGL; using StgSharp.Graphics.ShaderEdit; +using StgSharp.HighPerformance; using StgSharp.Mathematics; using System; @@ -46,11 +47,11 @@ namespace StgSharp.Graphics { private bool _isLookAtAvailable; - internal Matrix44 _lookAt; - internal Matrix44 _projection; - internal Matrix44 cameraAtt; - internal Matrix44 rotation; - internal Matrix44 rotationAtt; + internal MatrixKernel _lookAt; + internal MatrixKernel _projection; + internal MatrixKernel cameraAtt; + internal MatrixKernel rotation; + internal MatrixKernel rotationAtt; internal Radius _pitch; internal Radius _row; internal Radius _yaw; @@ -59,20 +60,20 @@ namespace StgSharp.Graphics public Camera() { - cameraAtt = Matrix44.Unit; + cameraAtt = MatrixKernel.Fp32Unit; _target = Vec3.Zero; up = Vec3.Zero; _isLookAtAvailable = false; - _lookAt = Matrix44.Unit; - rotationAtt = Matrix44.Unit; - _projection = new Matrix44(); + _lookAt = MatrixKernel.Fp32Unit; + rotationAtt = MatrixKernel.Fp32Unit; + _projection = new MatrixKernel(true); } public Camera(Vec3 position, Vec3 target, Vec3 up) : this() { - rotationAtt = Matrix44.Unit; - cameraAtt = new Matrix44(); + rotationAtt = MatrixKernel.Fp32Unit; + cameraAtt = new MatrixKernel(true); SetViewDirection(position, target, up); _pitch = Radius.Zero; _row = Radius.Zero; @@ -88,8 +89,8 @@ namespace StgSharp.Graphics if (_isLookAtAvailable) { return _lookAt; } - Matrix44 move = Matrix44.Unit; - move.colum3.vec -= cameraAtt.colum3.vec; + Matrix44 move = MatrixKernel.Fp32Unit; + move.colum3.vec -= cameraAtt.colum3; _lookAt = rotationAtt.Transpose * move; _isLookAtAvailable = true; return _lookAt; @@ -155,9 +156,7 @@ namespace StgSharp.Graphics public void SetViewDirection(Vec3 position, Vec3 target, Vec3 up) { Vec3 direction = position - target; - if ((position.reg == cameraAtt.colum3.reg) && - (this.up == up) && - (cameraAtt.colum2.reg == direction.reg)) { + if ((position.reg == cameraAtt.colum3.reg) && (this.up == up) && (cameraAtt.colum2.reg == direction.reg)) { return; } if (direction.GetLength() == 0) @@ -187,11 +186,7 @@ namespace StgSharp.Graphics InternalYaw(); } - public void SetViewRange( - Radius fovRadius, - Vec2 size, - Vec2 offset, - (float front, float back) dephRange) + public void SetViewRange(Radius fovRadius, Vec2 size, Vec2 offset, (float front, float back) dephRange) { float distance = _target.GetLength(), diff --git a/StgSharp.Common/Mathematics/Linear/Matrix.cs b/StgSharp.Common/Mathematics/Linear/Matrix.cs index 25dbc07a..d6824bd6 100644 --- a/StgSharp.Common/Mathematics/Linear/Matrix.cs +++ b/StgSharp.Common/Mathematics/Linear/Matrix.cs @@ -29,10 +29,13 @@ // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- using StgSharp.HighPerformance; - +using StgSharp.HighPerformance.Memory; using System; using System.Numerics; +using hlsfAllocator = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocator; +using hlsfHandle = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle; + namespace StgSharp.Mathematics { public abstract unsafe partial class Matrix where T: unmanaged, INumber @@ -42,6 +45,8 @@ namespace StgSharp.Mathematics private protected readonly int t_size = sizeof(T); + private protected Matrix() { } + public abstract ref T this[int column, int row] { get; @@ -53,6 +58,14 @@ namespace StgSharp.Mathematics set; } + public int ColumnCount { get; init; } + + public int RowCount { get; init; } + + protected int KernelColumnCount { get; init; } + + protected int KernelRowCount { get; init; } + public abstract MatrixKernel* GetMatrixKernel(int column, int row); [Obsolete("This method does not contain boarder check, so be careful on size or use indexer instead.", false)] @@ -67,9 +80,9 @@ namespace StgSharp.Mathematics public GCMatrix(int column, int row) { - int columnSet = (column + 3) / 4; - int rowSet = (row + 3) / 4; - buffer = new MatrixKernel[columnSet, rowSet]; + KernelColumnCount = (column + 3) / 4; + KernelRowCount = (row + 3) / t_count; + buffer = new MatrixKernel[KernelColumnCount, KernelRowCount]; } public override ref T this[int column, int row] @@ -77,7 +90,7 @@ namespace StgSharp.Mathematics get { int kernelColumn = column / 4, c = column % 4; - int kernelRow = row / t_count,r = row % t_count; + int kernelRow = row / t_count, r = row % t_count; ref MatrixKernel kernel = ref buffer[kernelColumn, kernelRow]; return ref kernel.UnsafeIndex(c, r); } @@ -104,6 +117,15 @@ namespace StgSharp.Mathematics internal unsafe class HlsfMatrix : Matrix where T: unmanaged, INumber { + private hlsfHandle handle; + + internal HlsfMatrix(int column, int row, hlsfAllocator allocator) + { + KernelColumnCount = (column + 3) / 4; + KernelRowCount = (row + 3) / t_count; + this.handle = allocator.Alloc((uint)(KernelColumnCount * KernelRowCount * sizeof(MatrixKernel))); + } + public override ref T this[int column, int row] => throw new NotImplementedException(); public override Matrix this[ReadOnlySpan column, ReadOnlySpan row] diff --git a/StgSharp.Native/StgSharp.Native.vcxproj b/StgSharp.Native/StgSharp.Native.vcxproj index 2f5c0ebb..ad230355 100644 --- a/StgSharp.Native/StgSharp.Native.vcxproj +++ b/StgSharp.Native/StgSharp.Native.vcxproj @@ -83,6 +83,7 @@ true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + All Console @@ -97,6 +98,7 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true + All Console @@ -139,7 +141,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Speed - NoListing + All stdcpp20 stdc17 CompileAsC @@ -157,6 +159,7 @@ + diff --git a/StgSharp.Native/sn-head/sn_intrinsic.h b/StgSharp.Native/sn-head/sn_intrinsic.h index d4d3654e..3efe9d3e 100644 --- a/StgSharp.Native/sn-head/sn_intrinsic.h +++ b/StgSharp.Native/sn-head/sn_intrinsic.h @@ -64,6 +64,7 @@ typedef void(SN_DECL *MATRIXTRANSPOSEPROC)(void *source, void *target); typedef void(SN_DECL *MATRIXDETPROC)(void *mat, void *transpose); typedef void(SN_DECL *MATARITHMETIC)(void *left, void *right, void *ans); typedef void(SN_DECL *SCALERMATARITHMETIC)(void *left, void *right, void *ans); +typedef void(SN_DECL* MATFMAPROC)(mat_kernel* left, mat_kernel* right, mat_kernel* ans); typedef uint64_t(SN_DECL *FACTORIALROC)(int n); @@ -102,12 +103,18 @@ INTERNAL float SN_DECL det_mat4(__4_columnset *matrix, __4_columnset *transpose) #pragma endregion +#pragma region fma + +INTERNAL void SN_DECL fma_44_sse(mat_kernel* left, mat_kernel* right); + +#pragma endregion + #pragma region dot -INTERNAL void FORCEINLINE SN_DECL dot_41_sse(__4_columnset *transpose, __m128 *vector, __m128 *ans); -INTERNAL void FORCEINLINE SN_DECL dot_31_sse(__3_columnset *transpose, __m128 *vector, __m128 *ans); -INTERNAL void FORCEINLINE SN_DECL dot_41_avx(__4_columnset *transpose, __m128 *vector, __m128 *ans); -INTERNAL void FORCEINLINE SN_DECL dot_31_avx(__3_columnset *transpose, __m128 *vector, __m128 *ans); +INTERNAL void SN_DECL dot_41_sse(__4_columnset *transpose, __m128 *vector, __m128 *ans); +INTERNAL void SN_DECL dot_31_sse(__3_columnset *transpose, __m128 *vector, __m128 *ans); +INTERNAL void SN_DECL dot_41_avx(__4_columnset *transpose, __m128 *vector, __m128 *ans); +INTERNAL void SN_DECL dot_31_avx(__3_columnset *transpose, __m128 *vector, __m128 *ans); INTERNAL void SN_DECL dot_32_sse(__3_columnset *transpose, __m128 *vector, __m128 *ans); INTERNAL void SN_DECL dot_32_avx(__3_columnset *transpose, __m128 *vector, __m128 *ans); @@ -144,6 +151,7 @@ typedef struct ssc_intrinsic { DOTPROC dot_42; DOTPROC dot_43; FACTORIALROC factorial_simd; + void (*fma_44)(void* left, void* right, void* ans); int (*index_pair)(short const *str, uint32_t target, int length); VECTORNORMALIZEPROC normalize_3; MATARITHMETIC sub_m2; diff --git a/StgSharp.Native/sn-src/intrinsic.c b/StgSharp.Native/sn-src/intrinsic.c index d74ae573..684f415f 100644 --- a/StgSharp.Native/sn-src/intrinsic.c +++ b/StgSharp.Native/sn-src/intrinsic.c @@ -88,6 +88,7 @@ void load_intrinsic_sse(ssc_intrinsic *context) context->sub_m3 = submatrix3_sse; context->sub_m4 = submatrix4_sse; context->factorial_simd = factorial_simd_sse; + context->fma_44 = fma_44_sse; } void load_intrinsic_avx(ssc_intrinsic *context) @@ -114,6 +115,7 @@ void load_intrinsic_avx(ssc_intrinsic *context) context->city_hash_simplify = city_hash_simplify_sse; context->index_pair = index_pair_sse; context->factorial_simd = factorial_simd_sse; + context->fma_44 = fma_44_sse; } void load_intrinsic_512(ssc_intrinsic *context) @@ -140,4 +142,5 @@ void load_intrinsic_512(ssc_intrinsic *context) context->city_hash_simplify = city_hash_simplify_sse; context->index_pair = index_pair_sse; context->factorial_simd = factorial_simd_sse; + context->fma_44 = fma_44_sse; } diff --git a/StgSharpDevelop.sln b/StgSharpDevelop.sln index 7b556540..70be4f04 100644 --- a/StgSharpDevelop.sln +++ b/StgSharpDevelop.sln @@ -53,8 +53,8 @@ Global {610B992B-BB34-49C3-9993-676C595FC12E}.Release|x64.ActiveCfg = Release|x64 {20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|ARM64.ActiveCfg = Debug|ARM64 {20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|ARM64.Build.0 = Debug|ARM64 - {20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|x64.ActiveCfg = Debug|x64 - {20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|x64.Build.0 = Debug|x64 + {20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|x64.ActiveCfg = Release|x64 + {20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|x64.Build.0 = Release|x64 {20CBFF26-6746-402E-992C-7B643E9423EB}.Release|ARM64.ActiveCfg = Release|ARM64 {20CBFF26-6746-402E-992C-7B643E9423EB}.Release|ARM64.Build.0 = Release|ARM64 {20CBFF26-6746-402E-992C-7B643E9423EB}.Release|x64.ActiveCfg = Release|x64