mpl going on good process
This commit is contained in:
@@ -79,19 +79,6 @@ Terminal-based user interface:
|
|||||||
- **EXPRESS Language**: Domain-specific language compilation
|
- **EXPRESS Language**: Domain-specific language compilation
|
||||||
- **Pipeline Processing**: Efficient data transformation workflows
|
- **Pipeline Processing**: Efficient data transformation workflows
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
### Technical Documentation
|
|
||||||
- [HLSF Allocator](StgSharp.Common/HighPerformance/Memory/InroductionToHLSF.md) - High-performance memory allocator documentation
|
|
||||||
- [Native Library Naming](StgSharp.Native/naming.md) - Native library file naming conventions
|
|
||||||
|
|
||||||
### Module-Specific Documentation
|
|
||||||
- **Mathematics**: Linear algebra, matrix operations, and mathematical utilities
|
|
||||||
- **Graphics**: OpenGL bindings, rendering, and graphics pipeline
|
|
||||||
- **High Performance**: SIMD operations, parallel computing, and memory management
|
|
||||||
- **Scripting**: General syntax analysis framework with EXPRESS language support
|
|
||||||
- **Modeling**: Geometric model loading and interpretation with STEP format support
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- .NET 8.0 or later
|
- .NET 8.0 or later
|
||||||
@@ -180,22 +167,12 @@ var handle = allocator.Alloc(1024);
|
|||||||
allocator.Free(handle);
|
allocator.Free(handle);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
StgSharp follows a modular architecture where each component can be used independently or in combination:
|
## Documentation
|
||||||
|
|
||||||
- **Core Layer**: Fundamental data structures and utilities
|
### Technical Documentation
|
||||||
- **Graphics Layer**: Rendering and graphics APIs
|
- [HLSF Allocator](StgSharp.Common/HighPerformance/Memory/InroductionToHLSF.md) - High-performance memory allocator documentation
|
||||||
- **Performance Layer**: High-performance computing and optimization
|
- [Native Library Naming](StgSharp.Native/naming.md) - Native library file naming conventions
|
||||||
- **Application Layer**: Game engine and application frameworks
|
|
||||||
- **Data Layer**: File processing and data modeling
|
|
||||||
|
|
||||||
## Performance Characteristics
|
|
||||||
|
|
||||||
- **Matrix Operations**: Optimized for large-scale computations
|
|
||||||
- **Memory Allocation**: O(1) allocation and deallocation with HLSF
|
|
||||||
- **Parallel Processing**: Multi-threaded execution with intelligent scheduling
|
|
||||||
- **SIMD Utilization**: Hardware-accelerated vector operations
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace StgSharp.Collections
|
||||||
|
{
|
||||||
|
public sealed class NotEnumerableList<T>(int capacity = 4)
|
||||||
|
{
|
||||||
|
|
||||||
|
private T[] _items = new T[capacity];
|
||||||
|
private int _size = 0;
|
||||||
|
|
||||||
|
public T this[int index]
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => (uint)index >= (uint)_size ? throw new ArgumentOutOfRangeException(nameof(index)) : _items[index];
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if ((uint)index >= (uint)_size) {
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
_items[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count => _size;
|
||||||
|
|
||||||
|
public int Capacity => _items.Length;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Add(T item)
|
||||||
|
{
|
||||||
|
if (_size == _items.Length) {
|
||||||
|
EnsureCapacity(_size + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_items[_size++] = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public Span<T> AsSpan()
|
||||||
|
{
|
||||||
|
return new Span<T>(_items, 0, _size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void FastClear()
|
||||||
|
{
|
||||||
|
// 只重置size,不清理数组内容
|
||||||
|
_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private void EnsureCapacity(int min)
|
||||||
|
{
|
||||||
|
if (_items.Length < min)
|
||||||
|
{
|
||||||
|
int newCapacity = _items.Length == 0 ? 4 : _items.Length * 2;
|
||||||
|
if (newCapacity < min) {
|
||||||
|
newCapacity = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.Resize(ref _items, newCapacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -42,25 +42,11 @@ using System.Threading.Tasks;
|
|||||||
namespace StgSharp.HighPerformance
|
namespace StgSharp.HighPerformance
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[InlineArray(16)]
|
||||||
public unsafe struct MatrixKernel<T> where T: unmanaged, INumber<T>
|
public unsafe struct MatrixKernel<T> where T: unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
private T c0r0;
|
private T c0r0;
|
||||||
private T c0r1;
|
|
||||||
private T c0r2;
|
|
||||||
private T c0r3;
|
|
||||||
private T c1r0;
|
|
||||||
private T c1r1;
|
|
||||||
private T c1r2;
|
|
||||||
private T c1r3;
|
|
||||||
private T c2r0;
|
|
||||||
private T c2r1;
|
|
||||||
private T c2r2;
|
|
||||||
private T c2r3;
|
|
||||||
private T c3r0;
|
|
||||||
private T c3r1;
|
|
||||||
private T c3r2;
|
|
||||||
private T c3r3;
|
|
||||||
|
|
||||||
public MatrixKernel()
|
public MatrixKernel()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace StgSharp.Mathematics
|
|||||||
int kernelColumn = column / 4, c = column % 4;
|
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<T> kernel = ref _buffer[kernelColumn + KernelColumnLength * kernelRow];
|
ref MatrixKernel<T> kernel = ref _buffer[kernelColumn + KernelColumnLength * kernelRow];
|
||||||
return ref kernel.UnsafeIndex(c, r);
|
return ref kernel[c, r];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ namespace StgSharp.Mathematics
|
|||||||
int kernelColumn = column / 4, c = column % 4;
|
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<T> kernel = ref _buffer[kernelColumn + (KernelColumnLength * kernelRow)];
|
ref MatrixKernel<T> kernel = ref _buffer[kernelColumn + (KernelColumnLength * kernelRow)];
|
||||||
return ref kernel.UnsafeIndex(c, r);
|
return ref kernel[c, r];
|
||||||
}
|
}
|
||||||
|
|
||||||
#region enumeration
|
#region enumeration
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ namespace StgSharp.Mathematics
|
|||||||
int kernelColumn = column / 4, c = column % 4;
|
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<T> kernel = ref k_buffer[(kernelColumn * kernelColumn) + kernelRow];
|
ref MatrixKernel<T> kernel = ref k_buffer[(kernelColumn * kernelColumn) + kernelRow];
|
||||||
return ref kernel.UnsafeIndex(c, r);
|
return ref kernel[c, r];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ namespace StgSharp.Mathematics
|
|||||||
int kernelColumn = column / 4, c = column % 4;
|
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<T> kernel = ref k_buffer[(kernelColumn * kernelColumn) + kernelRow];
|
ref MatrixKernel<T> kernel = ref k_buffer[(kernelColumn * kernelColumn) + kernelRow];
|
||||||
return ref kernel.UnsafeIndex(c, r);
|
return ref kernel[c, r];
|
||||||
}
|
}
|
||||||
|
|
||||||
~HlsfMatrix()
|
~HlsfMatrix()
|
||||||
|
|||||||
@@ -51,31 +51,35 @@ namespace StgSharp.Mathematics
|
|||||||
{
|
{
|
||||||
int length = _threads.Length,
|
int length = _threads.Length,
|
||||||
columnCount = left.PrimSize,
|
columnCount = left.PrimSize,
|
||||||
rowCount = right.PrimSize,
|
rowCount = right.PrimSize;
|
||||||
cAverage = left.PrimSize / length, cRemain = left.PrimSize % length,
|
(int c3, int c4) = FastDecompose(columnCount);
|
||||||
rAverage = right.PrimSize / length, rRemain = right.PrimSize % length;
|
|
||||||
|
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||||
|
package->Left = left.Source;
|
||||||
|
package->Right = right.Source;
|
||||||
|
package->Result = ans.Source;
|
||||||
|
package->LeftPrimOffset = left.PrimOffset;
|
||||||
|
package->RightPrimOffset = right.PrimOffset;
|
||||||
|
package->ResultPrimOffset = ans.PrimOffset;
|
||||||
|
package->LeftPrimStride = left.PrimStride;
|
||||||
|
package->RightPrimStride = right.PrimStride;
|
||||||
|
package->ResultPrimStride = ans.PrimStride;
|
||||||
|
package->LeftSecOffset = left.SecondaryOffset;
|
||||||
|
package->RightSecOffset = right.SecondaryOffset;
|
||||||
|
package->ResultSecOffset = ans.SecondaryOffset;
|
||||||
|
package->LeftSecStride = left.SecondaryStride;
|
||||||
|
package->RightSecStride = right.SecondaryStride;
|
||||||
|
package->ResultSecStride = ans.SecondaryStride;
|
||||||
|
package->PrimCount = left.PrimSize;
|
||||||
|
package->SecCount = left.SecondarySize;
|
||||||
|
package->ComputeHandle = (nint)Operation;
|
||||||
|
package->ElementSize = sizeof(T);
|
||||||
|
package->ComputeMode = 3;
|
||||||
|
|
||||||
|
int
|
||||||
|
small_4 = c4 / length,
|
||||||
|
larget_4
|
||||||
|
|
||||||
MatrixParallelTaskPackage<T> package = new()
|
|
||||||
{
|
|
||||||
Left = left.Source,
|
|
||||||
Right = right.Source,
|
|
||||||
Result = ans.Source,
|
|
||||||
LeftPrimOffset = left.PrimOffset,
|
|
||||||
RightPrimOffset = right.PrimOffset,
|
|
||||||
ResultPrimOffset = ans.PrimOffset,
|
|
||||||
LeftPrimStride = left.PrimStride,
|
|
||||||
RightPrimStride = right.PrimStride,
|
|
||||||
ResultPrimStride = ans.PrimStride,
|
|
||||||
LeftSecOffset = left.SecondaryOffset,
|
|
||||||
RightSecOffset = right.SecondaryOffset,
|
|
||||||
ResultSecOffset = ans.SecondaryOffset,
|
|
||||||
LeftSecStride = left.SecondaryStride,
|
|
||||||
RightSecStride = right.SecondaryStride,
|
|
||||||
ResultSecStride = ans.SecondaryStride,
|
|
||||||
PrimCount = left.PrimSize,
|
|
||||||
SecCount = left.SecondarySize,
|
|
||||||
ComputeHandle = (nint)Operation
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace StgSharp.Mathematics
|
|||||||
|
|
||||||
private static SlabAllocator<ScalarPacket> _scalarAllocator ;
|
private static SlabAllocator<ScalarPacket> _scalarAllocator ;
|
||||||
|
|
||||||
private static SlabAllocator<MatrixParallelTaskPackageNonGeneric> _wrapAllocator ;
|
private static SlabAllocator<MatrixParallelTaskPackageNonGeneric> _wrapAllocator;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static MatrixParallelTaskPackage<T>* CreateBaseTask<T>() where T: unmanaged, INumber<T>
|
public static MatrixParallelTaskPackage<T>* CreateBaseTask<T>() where T: unmanaged, INumber<T>
|
||||||
@@ -76,17 +76,13 @@ namespace StgSharp.Mathematics
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MatrixParallelTaskPackage<T>* FromTaskWrap<T>(MatrixParallelTaskPackage<T>* source, int offset)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static unsafe MatrixParallelTaskPackage<T>* FromExistPackage<T>(MatrixParallelTaskPackage<T>* exist)
|
||||||
where T: unmanaged, INumber<T>
|
where T: unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
MatrixParallelTaskPackage<T>* p = (MatrixParallelTaskPackage<T>*)_wrapAllocator.Allocate();
|
MatrixParallelTaskPackage<T>* ptr = (MatrixParallelTaskPackage<T>*)_wrapAllocator.Allocate();
|
||||||
/*
|
MatrixParallelTaskPackage<T>.Copy(exist, ptr);
|
||||||
*p = *source;
|
return ptr;
|
||||||
p->Left += offset * p->LeftStride;
|
|
||||||
p->Right += offset * p->RightStride;
|
|
||||||
p->Result += offset * p->ResultStride;
|
|
||||||
/**/
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -69,15 +69,33 @@ namespace StgSharp.Mathematics
|
|||||||
|
|
||||||
private static Thread[] _threads;
|
private static Thread[] _threads;
|
||||||
private static MatrixParallelWrap[] _wraps;
|
private static MatrixParallelWrap[] _wraps;
|
||||||
private static readonly (int a, int b)[] LookupTable = [ (1, 1), (0, 2), (3, 0), (2, 1), (1, 2), (0, 3), (3, 1), (2, 2), (1, 3), (0, 4), (3, 2), (2, 3), (1, 4), (0, 5), ];
|
private static readonly (int a, int b)[] LookupTable = [
|
||||||
private static volatile int RemainThreadCount = 0;
|
(1, 1),
|
||||||
|
(0, 2),
|
||||||
|
(3, 0),
|
||||||
|
(2, 1),
|
||||||
|
(1, 2),
|
||||||
|
(0, 3),
|
||||||
|
(3, 1),
|
||||||
|
(2, 2),
|
||||||
|
(1, 3),
|
||||||
|
(0, 4),
|
||||||
|
(3, 2),
|
||||||
|
(2, 3),
|
||||||
|
(1, 4),
|
||||||
|
(0, 5),
|
||||||
|
];
|
||||||
|
private static bool _meaningful;
|
||||||
|
|
||||||
|
private static int LargeWrapCount;
|
||||||
|
private static volatile int RemainThreadCount = 0;
|
||||||
|
private static int SmallWrapCount;
|
||||||
private static readonly object _lock = new();
|
private static readonly object _lock = new();
|
||||||
private static ThreadPriority _AfterWork = ThreadPriority.Lowest;
|
private static ThreadPriority _AfterWork = ThreadPriority.Lowest;
|
||||||
|
|
||||||
public static bool SupportParallel { get; } = Environment.ProcessorCount > 6;
|
public static bool SupportParallel { get; } = Environment.ProcessorCount > 6;
|
||||||
|
|
||||||
public static bool IsParallelMeaningful { get; } = Environment.ProcessorCount > 6 && IsInitialized;
|
public static bool IsParallelMeaningful => Environment.ProcessorCount > 6 && IsInitialized;
|
||||||
|
|
||||||
public static MatrixParallelWrap.Handle LeaderHandle { get; private/**/ set; }
|
public static MatrixParallelWrap.Handle LeaderHandle { get; private/**/ set; }
|
||||||
|
|
||||||
@@ -91,7 +109,7 @@ namespace StgSharp.Mathematics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static (int a, int b) FastDecompose(int c)
|
public static (int count_3, int count_4) FastDecompose(int c)
|
||||||
{
|
{
|
||||||
if (c < 7) {
|
if (c < 7) {
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
@@ -111,15 +129,25 @@ namespace StgSharp.Mathematics
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MatrixParallelFactory.Init();
|
MatrixParallelFactory.Init();
|
||||||
|
if (!SupportParallel)
|
||||||
|
{
|
||||||
|
IsInitialized = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
int count = Environment.ProcessorCount - 4;
|
int count = Environment.ProcessorCount - 4;
|
||||||
count = count == 5 ? 4 : count;
|
count = count == 5 ? 4 : count;
|
||||||
_threads = new Thread[count];
|
_threads = new Thread[count];
|
||||||
if (count < 6)
|
if (count < 6)
|
||||||
{
|
{
|
||||||
|
count = count == 3 ? 3 : 4;
|
||||||
_wraps = [ new MatrixParallelWrap(0, count, true) ];
|
_wraps = [ new MatrixParallelWrap(0, count, true) ];
|
||||||
|
(LargeWrapCount, SmallWrapCount) = count == 3 ? (1,0) : (0,1);
|
||||||
} else if (count == 6)
|
} else if (count == 6)
|
||||||
{
|
{
|
||||||
_wraps = [ new MatrixParallelWrap(0, 3, true), new MatrixParallelWrap(3, 3, false) ];
|
_wraps = [
|
||||||
|
new MatrixParallelWrap(0, 3, true),
|
||||||
|
new MatrixParallelWrap(3, 3, false)
|
||||||
|
];
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
(int _3wrap, int _4wrap) = FastDecompose(count);
|
(int _3wrap, int _4wrap) = FastDecompose(count);
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@@ -105,6 +106,7 @@
|
|||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <xmmintrin.h>
|
|
||||||
|
|
||||||
#ifndef SN_INTERNAL
|
#ifndef SN_INTERNAL
|
||||||
#define SN_INTERNAL
|
#define SN_INTERNAL
|
||||||
|
|
||||||
|
#include <xmmintrin.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define _CRT_SECURE_NO_WARNINGS 1
|
#define _CRT_SECURE_NO_WARNINGS 1
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ typedef uint64_t(SN_DECL *FACTORIALROC)(int n);
|
|||||||
|
|
||||||
#pragma region matix function
|
#pragma region matix function
|
||||||
|
|
||||||
INTERNAL void normalize(__m128 *source, __m128 *target);
|
INTERNAL void f32_normalize(VEC(float) * source, VEC(float) * target);
|
||||||
|
|
||||||
INTERNAL void SN_DECL f32_add_sse(MAT_KERNEL(float) const *left, MAT_KERNEL(float) const *right,
|
INTERNAL void SN_DECL f32_add_sse(MAT_KERNEL(float) const *left, MAT_KERNEL(float) const *right,
|
||||||
MAT_KERNEL(float) *restrict ans);
|
MAT_KERNEL(float) *restrict ans);
|
||||||
|
|||||||
@@ -9,11 +9,26 @@
|
|||||||
#define ZMMCOUNT(T) sizeof(T) / 4
|
#define ZMMCOUNT(T) sizeof(T) / 4
|
||||||
|
|
||||||
#define MAT_KERNEL(T) \
|
#define MAT_KERNEL(T) \
|
||||||
union { \
|
union mat_kernel_##T##{ \
|
||||||
__m128 xmm[XMMCOUNT(T)]; \
|
__m128 xmm[XMMCOUNT(T)]; \
|
||||||
__m256 ymm[YMMCOUNT(T)]; \
|
__m256 ymm[YMMCOUNT(T)]; \
|
||||||
__m512 zmm[ZMMCOUNT(T)]; \
|
__m512 zmm[ZMMCOUNT(T)]; \
|
||||||
T m[4][4]; \
|
T m[4][4]; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define VEC(T) \
|
||||||
|
union vec_##T##{ \
|
||||||
|
__m128 xmm[XMMCOUNT(T) / 4]; \
|
||||||
|
__m256 ymm[YMMCOUNT(T) / 4]; \
|
||||||
|
__m512 zmm[ZMMCOUNT(T) / 4]; \
|
||||||
|
T v[4]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#undef ELEMENTSIZE
|
||||||
|
#undef XMMCOUNT
|
||||||
|
#undef YMMCOUNT
|
||||||
|
#undef ZMMCOUNT
|
||||||
|
/**/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include "sn_intrinsic.h"
|
#include "sn_intrinsic.h"
|
||||||
|
|
||||||
// ans = left * right(T) + ans
|
// ans = left * right + ans
|
||||||
INTERNAL void SN_DECL f32_fma_sse(MAT_KERNEL(float) const *restrict left,
|
INTERNAL void SN_DECL f32_fma_sse(MAT_KERNEL(float) const *restrict left,
|
||||||
MAT_KERNEL(float) const *restrict right, MAT_KERNEL(float) *restrict ans)
|
MAT_KERNEL(float) const *restrict right,
|
||||||
|
MAT_KERNEL(float) *restrict ans)
|
||||||
{
|
{
|
||||||
register __m128 source0 = _mm_load_ps(&left->xmm[0]);
|
register __m128 source0 = _mm_load_ps(&left->xmm[0]);
|
||||||
register __m128 source1 = _mm_load_ps(&left->xmm[1]);
|
register __m128 source1 = _mm_load_ps(&left->xmm[1]);
|
||||||
|
|||||||
@@ -3,12 +3,7 @@
|
|||||||
INTERNAL int SN_DECL index_pair_sse(short const *str, uint32_t target, int length)
|
INTERNAL int SN_DECL index_pair_sse(short const *str, uint32_t target, int length)
|
||||||
{
|
{
|
||||||
int index = 0, result = 0, size = length, end = size - 8;
|
int index = 0, result = 0, size = length, end = size - 8;
|
||||||
__m128i s = {
|
__m128i s = _mm_set1_epi32(target);
|
||||||
target,
|
|
||||||
target,
|
|
||||||
target,
|
|
||||||
target,
|
|
||||||
};
|
|
||||||
__m128i vec, com;
|
__m128i vec, com;
|
||||||
|
|
||||||
while (index < end) {
|
while (index < end) {
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
#include "StgSharpNative.h"
|
#include "sn_intrinsic.h"
|
||||||
#include "sn_internal.h"
|
#include "sn_internal.h"
|
||||||
|
|
||||||
SN_API void SN_DECL normalize(__m128 *restrict source, __m128 *restrict target)
|
SN_API void SN_DECL normalize(VEC(float) *restrict source, VEC(float) *restrict target)
|
||||||
{
|
{
|
||||||
__m128 a_length_sq = _mm_mul_ps(*source, *source);
|
register __m128 s = _mm_load_ps(&source->xmm);
|
||||||
|
register __m128 a_length_sq = _mm_mul_ps(s, s);
|
||||||
a_length_sq = _mm_add_ps(a_length_sq,
|
a_length_sq = _mm_add_ps(a_length_sq,
|
||||||
_mm_shuffle_ps(a_length_sq, a_length_sq, _MM_SHUFFLE(2, 3, 0, 1)));
|
_mm_shuffle_ps(a_length_sq, a_length_sq, _MM_SHUFFLE(2, 3, 0, 1)));
|
||||||
a_length_sq = _mm_add_ss(a_length_sq,
|
a_length_sq = _mm_add_ss(a_length_sq,
|
||||||
_mm_shuffle_ps(a_length_sq, a_length_sq, _MM_SHUFFLE(0, 0, 3, 2)));
|
_mm_shuffle_ps(a_length_sq, a_length_sq, _MM_SHUFFLE(0, 0, 3, 2)));
|
||||||
|
|
||||||
__m128 a_inv_length = _mm_rsqrt_ps(a_length_sq);
|
__m128 a_inv_length = _mm_rsqrt_ps(a_length_sq);
|
||||||
*source = _mm_mul_ps(*source, a_inv_length);
|
s = _mm_mul_ps(s, a_inv_length);
|
||||||
|
|
||||||
__m128 dot_product = _mm_mul_ps(*target, *source);
|
__m128 dot_product = _mm_mul_ps(target->xmm[0], s);
|
||||||
dot_product = _mm_add_ps(dot_product,
|
dot_product = _mm_add_ps(dot_product,
|
||||||
_mm_shuffle_ps(dot_product, dot_product, _MM_SHUFFLE(2, 3, 0, 1)));
|
_mm_shuffle_ps(dot_product, dot_product, _MM_SHUFFLE(2, 3, 0, 1)));
|
||||||
dot_product = _mm_add_ss(dot_product,
|
dot_product = _mm_add_ss(dot_product,
|
||||||
_mm_shuffle_ps(dot_product, dot_product, _MM_SHUFFLE(0, 0, 3, 2)));
|
_mm_shuffle_ps(dot_product, dot_product, _MM_SHUFFLE(0, 0, 3, 2)));
|
||||||
|
|
||||||
__m128 b_orthogonal = _mm_sub_ps(*target, _mm_mul_ps(*source, dot_product));
|
__m128 b_orthogonal = _mm_sub_ps(target->xmm[0], _mm_mul_ps(s, dot_product));
|
||||||
|
|
||||||
__m128 b_length_sq = _mm_mul_ps(b_orthogonal, b_orthogonal);
|
__m128 b_length_sq = _mm_mul_ps(b_orthogonal, b_orthogonal);
|
||||||
b_length_sq = _mm_add_ps(b_length_sq,
|
b_length_sq = _mm_add_ps(b_length_sq,
|
||||||
@@ -27,5 +28,5 @@ SN_API void SN_DECL normalize(__m128 *restrict source, __m128 *restrict target)
|
|||||||
_mm_shuffle_ps(b_length_sq, b_length_sq, _MM_SHUFFLE(0, 0, 3, 2)));
|
_mm_shuffle_ps(b_length_sq, b_length_sq, _MM_SHUFFLE(0, 0, 3, 2)));
|
||||||
|
|
||||||
__m128 b_inv_length = _mm_rsqrt_ps(b_length_sq);
|
__m128 b_inv_length = _mm_rsqrt_ps(b_length_sq);
|
||||||
*target = _mm_mul_ps(b_orthogonal, b_inv_length);
|
target->xmm[0] = _mm_mul_ps(b_orthogonal, b_inv_length);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user