Switch matrix parallel to task stealing, type and wrap are refacored, thread execution core has not yet
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user