Switch matrix parallel to task stealing, type and wrap are refacored, thread execution core has not yet

This commit is contained in:
Youmu Liu
2026-02-24 15:12:23 +08:00
parent d99c1e3aa6
commit d62e59cb93
21 changed files with 1000 additions and 965 deletions
+42 -12
View File
@@ -1,5 +1,6 @@
#include "sn_target.h"
#include "sn_intrinsic.h"
#include "StgSharpNative.h"
static SIMDID global_simdid = { 0 };
@@ -76,11 +77,9 @@ static int is_intel_native_avx512(int family, int model)
}
}
SN_API SIMDID SN_DECL sn_get_simd_level()
SN_API SIMDID SN_DECL sn_get_simd_level_local()
{
if (global_simdid.mask) {
return global_simdid;
}
SIMDID _simdid = { 0 };
int eax = 0, ebx = 0, ecx = 0, edx = 0;
@@ -114,6 +113,7 @@ SN_API SIMDID SN_DECL sn_get_simd_level()
uint64_t avx512_bits = 0;
uint64_t amx_bits = 0;
uint64_t avx_bits = 0;
uint64_t avx10_bits = 0;
/* Baseline main level */
if (has_sse42)
@@ -135,15 +135,17 @@ SN_API SIMDID SN_DECL sn_get_simd_level()
const int has_vbmi = (ecx & (1 << 1)) != 0;
const int has_vbmi2 = (ecx & (1 << 6)) != 0;
/* leaf 7, subleaf 1 for BF16/FP16 */
/* AMX in leaf 7 subleaf 0 EDX bits 24/25/26 — capture before
overwriting regs with subleaf 1 */
const int has_amx_tile = (edx & (1 << 24)) != 0;
const int has_amx_int8 = (edx & (1 << 25)) != 0;
const int has_amx_bf16 = (edx & (1 << 22)) != 0;
/* leaf 7, subleaf 1 for BF16/FP16/AVX10 convergence */
get_cpuid(7, 1, &eax, &ebx, &ecx, &edx);
const int has_bf16 = (eax & (1 << 5)) != 0; /* AVX512_BF16 */
const int has_fp16 = (eax & (1 << 23)) != 0; /* AVX512_FP16 */
/* AMX in leaf 7 subleaf 0 EDX bits 24/25/26 */
const int has_amx_tile = (edx & (1 << 24)) != 0;
const int has_amx_int8 = (edx & (1 << 25)) != 0;
const int has_amx_bf16 = (edx & (1 << 26)) != 0;
const int has_avx10 = (edx & (1 << 19)) != 0; /* AVX10 convergence */
if (has_avx2) {
avx_bits |= SIMDID_AVX2;
@@ -194,11 +196,39 @@ SN_API SIMDID SN_DECL sn_get_simd_level()
amx_bits |= SIMDID_AMX_BF16;
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AMX);
}
/* AVX10 detection — requires AVX10 convergence bit
(leaf 7 subleaf 1 EDX[19]) and leaf 0x24 */
if (has_avx10) {
int a10_eax = 0, a10_ebx = 0, a10_ecx = 0, a10_edx = 0;
get_cpuid(0x24, 0, &a10_eax, &a10_ebx, &a10_ecx, &a10_edx);
const int avx10_ver = a10_ebx & 0xFF;
if (avx10_ver >= 1) {
avx10_bits |= SIMDID_AVX10 | SIMDID_AVX10_V1;
if (avx10_ver >= 2)
avx10_bits |= SIMDID_AVX10_V2;
if (a10_ebx & (1 << 17))
avx10_bits |= SIMDID_AVX10_256W;
if (a10_ebx & (1 << 18))
avx10_bits |= SIMDID_AVX10_512W;
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX10);
}
}
}
}
global_simdid.mask = root | manu | main_lvl | SIMDID_PACK_AVX512(avx512_bits) |
SIMDID_PACK_AMX(amx_bits) | SIMDID_PACK_AVX(avx_bits);
_simdid.mask = root | manu | main_lvl | SIMDID_PACK_AVX512(avx512_bits) |
SIMDID_PACK_AMX(amx_bits) | SIMDID_PACK_AVX(avx_bits) |
SIMDID_PACK_AVX10(avx10_bits);
return _simdid;
}
SN_API SIMDID SN_DECL sn_get_simd_level()
{
if (global_simdid.mask) {
return global_simdid;
}
global_simdid = sn_get_simd_level_local();
return global_simdid;
}
+13 -4
View File
@@ -14,14 +14,21 @@
#endif // _MSC_VER
PRIVATE void load_intrinsic_sse(sn_intrinsic *context, SIMDID id);
PRIVATE void load_intrinsic_avx_dual(sn_intrinsic *context, SIMDID id);
PRIVATE void load_intrinsic_avx(sn_intrinsic *context, SIMDID id);
PRIVATE void load_intrinsic_512_dual(sn_intrinsic *context, SIMDID id);
PRIVATE void load_intrinsic_512(sn_intrinsic *context, SIMDID id);
SN_API SIMDID load_intrinsic_function(void *intrinsic_context)
SN_API SIMDID load_intrinsic_function(void *intrinsic_context, uint64_t id)
{
sn_null_assert(intrinsic_context);
SIMDID simdid = sn_get_simd_level();
SIMDID simdid;
if (id) {
simdid.mask = id;
} else {
simdid = sn_get_simd_level();
}
sn_intrinsic *context = (sn_intrinsic *)intrinsic_context;
@@ -33,6 +40,8 @@ SN_API SIMDID load_intrinsic_function(void *intrinsic_context)
load_intrinsic_avx(context, simdid);
break;
case SIMDID_MAIN_LVL_AVX512:
case SIMDID_MAIN_LVL_AMX:
case SIMDID_MAIN_LVL_AVX10:
load_intrinsic_512(context, simdid);
break;
}
@@ -75,8 +84,8 @@ void load_intrinsic_sse(sn_intrinsic *context, SIMDID id)
void load_intrinsic_avx(sn_intrinsic *context, SIMDID id)
{
char avx_seg = id.make_byte[5];
char is_fma = (avx_seg & 1 << 3) != 0;
char is_f16c = (avx_seg & 1 << 4) != 0;
char is_fma = (avx_seg & SIMDID_AVX_FMA) != 0;
char is_f16c = (avx_seg & SIMDID_AVX_F16C) != 0;
context->city_hash_simplify = city_hash_simplify_sse;
context->factorial_simd = factorial_simd_sse;
-26
View File
@@ -7,34 +7,8 @@
#define _FMA_SELECT(i) _MM_SHUFFLE(i, i, i, i)
/*
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe MatrixKernel<T>* GetKernelAddressUnsafe<T>(
MatrixKernel<T>* buffer,
int colLength,
int x,
int y
) where T : unmanaged, INumber<T>
{
return buffer + (colLength * x + y);
}
*/
#define GET_INDEX(col_len, x, y) (col_len * x + y)
/*
for (int k = 0; k < commonK; k += 1) {
NativeIntrinsic.Context
.mat[f64].kernel_fma(
(MatrixPanel*)GetKernelAddressUnsafe((MatrixKernel<double>*)leftBuffer,
ansHeight, k, j),
(MatrixPanel*)GetKernelAddressUnsafe((MatrixKernel<double>*)rightBuffer,
commonK, j, k),
(MatrixPanel*)GetKernelAddressUnsafe((MatrixKernel<double>*)ansBuffer,
ansHeight, i, j));
}
*/
// float
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(float, sse, , fma)
+31
View File
@@ -0,0 +1,31 @@
#include "sn_target.h"
#include "StgSharpNative.h"
#if SN_IS_OS(SN_OS_LINUX)
#define _GNU_SOURCE
#include <pthread.h>
#include <sched.h>
#endif
/* Pin the calling thread to a single logical processor.
* core_id: zero-based logical processor index.
* Silently ignored if core_id is out of range or the OS call fails. */
SN_API void SN_DECL sn_set_thread_affinity(int core_id)
{
if (core_id < 0)
return;
#if SN_IS_OS(SN_OS_WINDOWS)
/* windows.h already included via sn_internal.h */
if (core_id >= 64)
return;
DWORD_PTR mask = (DWORD_PTR)1 << core_id;
SetThreadAffinityMask(GetCurrentThread(), mask);
#elif SN_IS_OS(SN_OS_LINUX)
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(core_id, &set);
pthread_setaffinity_np(pthread_self(), sizeof(set), &set);
#endif
}