time service contains bug, it cannot stop after edge

This commit is contained in:
Youmu Liu
2025-12-08 18:02:09 +08:00
parent 588fa867af
commit f960982bd3
17 changed files with 313 additions and 188 deletions
+2 -2
View File
@@ -148,7 +148,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="sn-src\k_build_panel.c" />
<ClCompile Include="sn-src\k_panel.c" />
<ClCompile Include="sn-src\k_basicop.c" />
<ClCompile Include="sn-src\dllmain.c" />
<ClCompile Include="sn-src\k_bufop.c" />
@@ -156,7 +156,7 @@
<ClCompile Include="sn-src\k_fma.c" />
<ClCompile Include="sn-src\str_hash.c" />
<ClCompile Include="sn-src\load_intrinsic.c">
<FileType>CppCode</FileType>
<FileType>CCode</FileType>
</ClCompile>
<ClCompile Include="sn-src\load_glfw.c" />
<ClCompile Include="sn-src\sn_native.c" />
@@ -51,7 +51,7 @@
<ClCompile Include="sn-src\k_bufop.c">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="sn-src\k_build_panel.c">
<ClCompile Include="sn-src\k_panel.c">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
+16 -15
View File
@@ -131,6 +131,8 @@ typedef void(SN_DECL *BUF_PROC_LRA)(mat_kernel *left, mat_kernel *right, mat_ker
#pragma region matrix panel function type
typedef void(SN_DECL *PANEL_PROC)(mat_panel *panel, mat_kernel *kernel, int col_length,
int row_length, int col_index, int row_index);
typedef void(SN_DECL *PNL_PROC_LRA)(mat_panel *left, mat_panel *right, mat_panel *ans);
typedef void(SN_DECL *PNL_PROC_RA)(mat_panel *right, mat_panel *ans);
typedef void(SN_DECL *PNL_PROC_LRAS)(mat_panel *left, mat_panel *right, mat_panel *ans,
@@ -250,22 +252,21 @@ INTERNAL int SN_DECL index_pair_sse(short const *str, uint32_t target, int lengt
#pragma endregion
typedef void(SN_DECL *BUILD_PANEL_PROC)(mat_panel *panel, mat_kernel *kernel, int col_length,
int row_length, int col_index, int row_index);
// Reordered to match C# IntrinsicContext field order
// C# order: city_hash_simplify, f32_add, f32_fill, f32_fma, f32_scalar_mul, f32_sub, f32_transpose, factorial_simd, index_pair, normalize_3
// Mirrors C# IntrinsicContext field order so managed/unmanaged layouts stay in sync.
typedef struct sn_intrinsic {
HASH city_hash_simplify; // city_hash_simplify
BUF_PROC_LRA f32_buffer_add; // f32_add
BUF_PROC_AS f32_buffer_fill; // f32_fill
PNL_PROC_LRA f32_panel_fma; // f32_fma (panel variant)
BUF_PROC_LRA f32_kernel_scalar_mul; // f32_scalar_mul (right+ans+scalar variant mapped here)
BUF_PROC_LRA f32_kernel_sub; // f32_sub
KER_PROC_RA f32_kernel_transpose; // f32_transpose
FACTORIALROC factorial_simd; // factorial_simd
INDEX_PAIR index_pair; // index_pair
VECTORNORMALIZEPROC f32_normalize_3; // normalize_3
HASH city_hash_simplify;
BUF_PROC_LRA f32_buffer_add;
BUF_PROC_AS f32_buffer_fill;
BUF_PROC_RAS f32_buffer_scalar_mul;
BUF_PROC_LRA f32_buffer_sub;
KER_PROC_RA f32_buffer_transpose;
PANEL_PROC f32_build_panel;
VECTORNORMALIZEPROC f32_normalize_3;
PNL_PROC_LRA f32_panel_fma;
PANEL_PROC f32_store_panel;
FACTORIALROC factorial_simd;
INDEX_PAIR index_pair;
BUF_PROC_RAS variant;
} sn_intrinsic;
typedef enum most_advanced_instruction {
+36 -23
View File
@@ -1,14 +1,17 @@
#ifndef SN_MATKERNEL
#define SN_MATKERNEL
#define ELEMENTSIZE(T) sizeof(T)
#define XMMCOUNT(T) sizeof(T)
#define YMMCOUNT(T) sizeof(T) / 2
#define ZMMCOUNT(T) sizeof(T) / 4
#include <immintrin.h>
#include <stdint.h>
#include "sn_internal.h"
/* Kernel storage unions for a fixed 4x4 block. */
#define ELEMENTSIZE(T) sizeof(T)
#define XMMCOUNT(T) (sizeof(T))
#define YMMCOUNT(T) (sizeof(T) / 2)
#define ZMMCOUNT(T) (sizeof(T) / 4)
#define MAT_KERNEL(T) \
union { \
__m128 xmm[XMMCOUNT(T) / 4]; \
@@ -25,7 +28,8 @@
T v[4]; \
}
#endif
/* Provide a named alias for the zero kernel type to ensure consistent linkage in C++. */
typedef MAT_KERNEL(uint64_t) sn_zero_kernel_u64;
/* Helpers (all compile-time): */
#define SN_LANES(T_VEC, T) (sizeof(T_VEC) / sizeof(T))
@@ -48,8 +52,8 @@
- SIMD view remains integer-typed; cast inside micro-kernels to the
appropriate floating-point/integer vector type on demand.
*/
#define MAT_PANEL_SQ_MIN(T, T_VEC, MINQ) \
SN_ALIGNAS(sizeof(T_VEC)) union { \
#define MAT_PANEL_SQ_MIN_NOALIGN(T, T_VEC, MINQ) \
union { \
T_VEC vec[PANEL_Q(T, T_VEC, MINQ)][PANEL_CHUNKS(T, T_VEC, MINQ)]; \
T flat[PANEL_Q(T, T_VEC, MINQ) * PANEL_Q(T, T_VEC, MINQ)]; \
}
@@ -63,44 +67,53 @@
/* SSE panel layout: column-major buffer holding 4 logical columns with MINQ=4.
Columns: each column packs up to four scalars so ALIGN equals sizeof(__m128).
Alignment: every column boundary lands on a 16-byte multiple for XMM loads. */
#define MAT_PANEL_SSE(T) MAT_PANEL_SQ_MIN(T, __m128, 4)
#define MAT_PANEL_SSE(T) SN_ALIGNAS(16) MAT_PANEL_SQ_MIN_NOALIGN(T, __m128, 4)
/* AVX2 panel layout: column-major buffer holding 8 logical columns with MINQ=8.
Columns: each column stores eight elements via two 256-bit chunks when T is 32-bit.
Alignment: column starts are 32-byte aligned so AVX2 loads/stores remain contiguous. */
#define MAT_PANEL_AVX(T) MAT_PANEL_SQ_MIN(T, __m256, 8)
#define MAT_PANEL_AVX(T) SN_ALIGNAS(32) MAT_PANEL_SQ_MIN_NOALIGN(T, __m256, 8)
/* AVX-512 panel layout: column-major buffer holding 8 or more columns depending on T.
Columns: each column expands to ceil(Q/lanes) ZMM chunks; default MINQ=8 keeps double-wide tiles.
Alignment: column starts sit on 64-byte boundaries to match AVX-512 streaming access. */
#define MAT_PANEL_512(T) MAT_PANEL_SQ_MIN(T, __m512, 8)
#define MAT_PANEL_512(T) SN_ALIGNAS(64) MAT_PANEL_SQ_MIN_NOALIGN(T, __m512, 8)
/* Global zero kernel declaration (defined in dllmain.c), aligned to 64 bytes */
#ifdef __cplusplus
extern "C" {
#endif
extern __declspec(align(64)) sn_zero_kernel_u64 SN_ZERO_KERNEL;
#ifdef __cplusplus
}
#endif
/* Access helpers (all compile-time friendly):
Given Q = PANEL_Q(...), CH = PANEL_CHUNKS(...), R = lanes per vector:
- Column c occupies vec[c][0..CH-1].
- Row r inside column c is located at vec[c][r / R] with lane (r % R).
*/
/* Global zero kernel declaration (defined in dllmain.c), aligned to 64 bytes */
#ifdef __cplusplus
extern "C" {
#endif
__declspec(align(64)) extern MAT_KERNEL(uint64_t) SN_ZERO_KERNEL;
#ifdef __cplusplus
}
#endif
#define PANEL_COL_VEC(panel_obj, c, chunk) ((panel_obj).vec[(int)(c)][(int)(chunk)])
/* Scalar flat index helper for column-major addressing */
#define PANEL_ELEM(panel_obj, T, T_VEC, MINQ, r, c) \
((panel_obj).flat[(int)(c) * PANEL_Q(T, T_VEC, MINQ) + (int)(r)])
/* API macros */
#define BUILD_PANEL(arch, element) build_panel_##arch##_##element
#include "sn_internal.h"
#define STORE_PANEL(arch, element) store_panel_##arch##_##element
#define DECLARE_BUILD_PANEL(arch, element) \
INTERNAL void SN_DECL BUILD_PANEL(arch, element)( \
MAT_PANEL_##arch(element) *restrict panel, \
MAT_KERNEL(element) const *const matrix, int col_length, int row_length, \
int col_index, int row_index)
#define DECLARE_STORE_PANEL(arch, element) \
INTERNAL void SN_DECL STORE_PANEL(arch, element)(MAT_KERNEL(element) *restrict matrix, \
MAT_PANEL_##arch(element) \
const *const panel, \
int col_length, int row_length, \
int col_index, int row_index)
/* Declarations for AVX float variant */
DECLARE_BUILD_PANEL(AVX, float);
DECLARE_STORE_PANEL(AVX, float);
#endif /* SN_MATKERNEL */
+9 -2
View File
@@ -1,16 +1,23 @@
#include "StgSharpNative.h"
#include "sn_matkernel.h"
#include <stdint.h>
#ifdef _WIN32
/* Define and initialize a global zero kernel aligned to 64 bytes for universal ISA usage */
__declspec(align(64)) MAT_KERNEL(uint64_t) SN_ZERO_KERNEL;
#ifdef __cplusplus
extern "C" {
#endif
__declspec(align(64)) sn_zero_kernel_u64 SN_ZERO_KERNEL;
#ifdef __cplusplus
}
#endif
static void init_zero_kernel(void)
{
for (int c = 0; c < 4; ++c) {
for (int r = 0; r < 4; ++r) {
SN_ZERO_KERNEL.m[r][c] = 0.0;
SN_ZERO_KERNEL.m[r][c] = 0;
}
}
}
-42
View File
@@ -1,42 +0,0 @@
#include "sn_matkernel.h"
DECLARE_BUILD_PANEL(AVX, float)
{
const int Q = 8; /* fixed for AVX float panel */
/* Neighbor kernels; substitute global zero kernel where out-of-bounds */
const int has_right = (col_index + 1) < col_length;
const int has_bottom = (row_index + 1) < row_length;
const MAT_KERNEL(float) *const k_lt = matrix + (col_index * row_length + row_index);
const MAT_KERNEL(float) *const k_rt =
has_right ? (matrix + ((col_index + 1) * row_length + row_index)) :
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
const MAT_KERNEL(float) *const k_lb =
has_bottom ? (matrix + (col_index * row_length + (row_index + 1))) :
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
const MAT_KERNEL(float) *const k_rb =
(has_right && has_bottom) ?
(matrix + ((col_index + 1) * row_length + (row_index + 1))) :
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
register __m128 top128, bot128;
register __m256 col256;
for (int pc = 0; pc < Q; ++pc) {
const int is_right_half = (pc >= 4);
const int kc_col = pc & 3; /* column index inside 4x4 kernel */
const MAT_KERNEL(float) *src_top = is_right_half ? k_rt : k_lt;
const MAT_KERNEL(float) *src_bot = is_right_half ? k_rb : k_lb;
/* Vector loads: each kernel column is a compact __m128 */
top128 = src_top->xmm[kc_col];
bot128 = src_bot->xmm[kc_col];
/* Combine into an AVX column: low 128 = top, high 128 = bottom */
col256 = _mm256_set_m128(bot128, top128);
PANEL_COL_VEC((*panel), pc, 0) = col256;
}
}
+98
View File
@@ -0,0 +1,98 @@
#include "sn_matkernel.h"
DECLARE_BUILD_PANEL(AVX, float)
{
const int Q = 8; /* fixed for AVX float panel */
/* Neighbor kernels; substitute global zero kernel where out-of-bounds */
const int has_right = (col_index + 1) < col_length;
const int has_bottom = (row_index + 1) < row_length;
const MAT_KERNEL(float) *const k_lt = matrix + (col_index * row_length + row_index);
const MAT_KERNEL(float) *const k_rt =
has_right ? (matrix + ((col_index + 1) * row_length + row_index)) :
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
const MAT_KERNEL(float) *const k_lb =
has_bottom ? (matrix + (col_index * row_length + (row_index + 1))) :
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
const MAT_KERNEL(float) *const k_rb =
(has_right && has_bottom) ?
(matrix + ((col_index + 1) * row_length + (row_index + 1))) :
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
register __m128 top128, bot128;
register __m256 col256;
for (int pc = 0; pc < Q; ++pc) {
const int is_right_half = (pc >= 4);
const int kc_col = pc & 3; /* column index inside 4x4 kernel */
const MAT_KERNEL(float) *src_top = is_right_half ? k_rt : k_lt;
const MAT_KERNEL(float) *src_bot = is_right_half ? k_rb : k_lb;
/* Vector loads: each kernel column is a compact __m128 */
top128 = src_top->xmm[kc_col];
bot128 = src_bot->xmm[kc_col];
/* Combine into an AVX column: low 128 = top, high 128 = bottom */
col256 = _mm256_set_m128(bot128, top128);
PANEL_COL_VEC((*panel), pc, 0) = col256;
}
}
DECLARE_STORE_PANEL(AVX, float)
{
const int Q = 8; /* fixed for AVX float panel */
/* Local dummy kernel to swallow out-of-bounds writes; no init needed */
MAT_KERNEL(float) zero;
const int has_right = (col_index + 1) < col_length;
const int has_bottom = (row_index + 1) < row_length;
MAT_KERNEL(float) *const k_lt = (col_index < col_length && row_index < row_length) ?
(matrix + (col_index * row_length + row_index)) :
&zero;
MAT_KERNEL(float) *const k_rt =
has_right && (row_index < row_length) ?
(matrix + ((col_index + 1) * row_length + row_index)) :
&zero;
MAT_KERNEL(float) *const k_lb =
has_bottom && (col_index < col_length) ?
(matrix + (col_index * row_length + (row_index + 1))) :
&zero;
MAT_KERNEL(float) *const k_rb =
(has_right && has_bottom) ?
(matrix + ((col_index + 1) * row_length + (row_index + 1))) :
&zero;
register __m128 top128, bot128;
int i = 0;
for (; i < Q / 2; i++) {
const int kc_col = i; /* column index inside 4x4 kernel */
/* Load the panel column vector */
const __m256 col256 = PANEL_COL_VEC((*panel), i, 0);
/* Split into top/bottom halves */
top128 = _mm256_castps256_ps128(col256); /* low 128 */
bot128 = _mm256_extractf128_ps(col256, 1); /* high 128 */
/* Store back into kernels directly (out-of-bounds writes go to dummy) */
k_rt->xmm[kc_col] = top128;
k_rb->xmm[kc_col] = bot128;
}
for (; i < Q; i++) {
const int kc_col = i - 4; /* column index inside 4x4 kernel */
/* Load the panel column vector */
const __m256 col256 = PANEL_COL_VEC((*panel), i, 0);
/* Split into top/bottom halves */
top128 = _mm256_castps256_ps128(col256); /* low 128 */
bot128 = _mm256_extractf128_ps(col256, 1); /* high 128 */
/* Store back into kernels directly (out-of-bounds writes go to dummy) */
k_lt->xmm[kc_col] = top128;
k_lb->xmm[kc_col] = bot128;
}
}
+12 -9
View File
@@ -68,9 +68,10 @@ void load_intrinsic_sse(sn_intrinsic *context)
context->f32_buffer_add = BUF_PROC(float, sse, add);
context->f32_panel_fma = KER_PROC(float, sse, fma);
context->f32_buffer_fill = BUF_PROC(float, sse, fill);
context->f32_kernel_scalar_mul = BUF_PROC(float, sse, scalar_mul);
context->f32_kernel_sub = BUF_PROC(float, sse, sub);
context->f32_kernel_transpose = KER_PROC(float, sse, transpose);
context->variant = BUF_PROC(float, sse, scalar_mul);
context->f32_buffer_sub = BUF_PROC(float, sse, sub);
context->f32_buffer_transpose = KER_PROC(float, sse, transpose);
context->f32_buffer_scalar_mul = BUF_PROC(float, sse, scalar_mul);
context->f32_normalize_3 = f32_normalize;
}
@@ -82,9 +83,10 @@ void load_intrinsic_avx(sn_intrinsic *context)
context->f32_buffer_add = BUF_PROC(float, avx, add);
context->f32_panel_fma = KER_PROC(float, sse, fma);
context->f32_buffer_fill = BUF_PROC(float, avx, fill);
context->f32_kernel_scalar_mul = BUF_PROC(float, avx, scalar_mul);
context->f32_kernel_sub = BUF_PROC(float, avx, sub);
context->f32_kernel_transpose = KER_PROC(float, avx, transpose);
context->variant = BUF_PROC(float, avx, scalar_mul);
context->f32_buffer_sub = BUF_PROC(float, avx, sub);
context->f32_buffer_transpose = KER_PROC(float, avx, transpose);
context->f32_buffer_scalar_mul = BUF_PROC(float, avx, scalar_mul);
context->f32_normalize_3 = f32_normalize;
}
@@ -96,8 +98,9 @@ void load_intrinsic_512(sn_intrinsic *context)
context->f32_buffer_add = BUF_PROC(float, 512, add);
context->f32_panel_fma = KER_PROC(float, sse, fma);
context->f32_buffer_fill = BUF_PROC(float, 512, fill);
context->f32_kernel_scalar_mul = BUF_PROC(float, 512, scalar_mul);
context->f32_kernel_sub = BUF_PROC(float, 512, sub);
context->f32_kernel_transpose = KER_PROC(float, 512, transpose);
context->variant = BUF_PROC(float, 512, scalar_mul);
context->f32_buffer_sub = BUF_PROC(float, 512, sub);
context->f32_buffer_transpose = KER_PROC(float, 512, transpose);
context->f32_buffer_scalar_mul = BUF_PROC(float, 512, scalar_mul);
context->f32_normalize_3 = f32_normalize;
}