new compute kernel design, less mem read delay

This commit is contained in:
Nitload
2026-04-07 01:04:05 +08:00
parent d702b3224c
commit 12a216d404
47 changed files with 225 additions and 145 deletions
+6 -32
View File
@@ -12,30 +12,13 @@
#include "../lib/stbi/stb_image.h"
#include "gl.h"
#include "wgl.h"
// #include "wgl.h"
#define GLFWAPI INTERNAL
#include "glfw\glfw3.h"
#include <immintrin.h>
#include <assert.h>
#include <glfw_function.h>
#ifndef SN_APIDEF
#ifdef _WIN32
#define SN_API __declspec(dllexport)
#elif defined _LINUX_
#define SN_API __attribute__((dllexport))
#elif defined _APPLE_
#define SN_API __attribute__((visibility("default")))
#else
#define SN_API
#endif
#endif // ! SN_APIDEF
#if __cplusplus
extern "C" {
#endif
#define byte char
#define cs_char uint16_t
#define sn_null_assert(ptr) assert(ptr != NULL)
@@ -65,21 +48,12 @@ SN_API void SN_DECL unloadImageData(Image *out);
SN_API char *SN_DECL readLog(void);
SN_API void SN_DECL load_glfw_functions(GLFWFunctionTable *table);
SN_API void SN_DECL load_intrinsic_function(void *intrinsic_context, uint64_t id);
#pragma region numa
SN_API SIMDID SN_DECL sn_get_unite_simd(SIMDID left, SIMDID right);
SN_API int SN_DECL sn_compare_simd(SIMDID left, SIMDID right);
SN_API void SN_DECL sn_set_thread_affinity(int core_id);
SN_API int SN_DECL sn_get_numa_overall(int *out_numa_count, int *count_of_each_numa);
SN_API int SN_DECL sn_get_numa_each(int numa_id, uint64_t *in_numa_cpuid, uint64_t *global_cpuid);
SN_API SIMDID SN_DECL sn_get_simd_level_global();
/* Per-core variant: always re-executes CPUID, never caches.
* Must be called on the target core (after affinity is set). */
SN_API SIMDID SN_DECL sn_get_simd_level_local();
SN_API SIMDID SN_DECL sn_get_simd_level_global();
#pragma endregion
#ifdef __cplusplus
}
#endif
SN_API SIMDID SN_DECL sn_get_unite_simd(SIMDID left, SIMDID right);
SN_API int SN_DECL sn_compare_simd(SIMDID left, SIMDID right);
SN_API void SN_DECL sn_set_thread_affinity(int core_id);
#endif
+4 -6
View File
@@ -2,7 +2,7 @@
#ifndef SN_INTERNAL
#define SN_INTERNAL
#include <immintrin.h>
#include <xmmintrin.h>
#define UNSAFE_AS(type, expr) *(type *)&(expr)
@@ -13,17 +13,20 @@
#define SN_MAT_DECL __cdecl __forceinline
#define SN_API __declspec(dllexport)
#define FORCEINLINE __forceinline
#define NOINLINE __declspec(noinline)
#include <windows.h>
#elif defined(__clang__) || defined(__GNUC__)
#define SN_DECL __attribute__((cdecl))
#define SN_MAT_DECL __attribute__((cdecl)) __attribute__((always_inline))
#define SN_API __attribute__((dllexport))
#define FORCEINLINE __attribute__((always_inline))
#define NOINLINE __attribute__((noinline))
#else
#define SN_API
#define SN_DECL
#define SN_MAT_DECL
#define FORCEINLINE
#define NOINLINE
#endif
#if defined(_MSC_VER)
@@ -37,9 +40,4 @@
#define PRIVATE static
#define INTERNAL extern
#define SN_PTR_CAST(type, expr) ((type *)(void *)(expr))
#define SN_CONST_PTR_CAST(type, expr) ((type const *)(void const *)(expr))
#define SN_REF_CAST(type, expr) ((type *)(void *)&(expr))
#define SN_CONST_REF_CAST(type, expr) ((type const *)(void const *)&(expr))
#endif //
@@ -5,6 +5,13 @@
#include "sn_intrinsic.h"
#include "sn_intrinsic.std.h"
#ifndef SN_X86_TARGET_ATTR_sse
#define SN_X86_TARGET_ATTR_sse SN_CLANG_TARGET_ATTR("sse2")
#define SN_X86_TARGET_ATTR_avx SN_CLANG_TARGET_ATTR("avx")
#define SN_X86_TARGET_ATTR_avx_fma SN_CLANG_TARGET_ATTR("avx,fma")
#define SN_X86_TARGET_ATTR_512 SN_CLANG_TARGET_ATTR("avx512f,avx512vl")
#endif
// -----------------------------------------------------------------------------
// SIMDID layout helpers (see SIMDID.x86.md)
// bits [3..0] : Root ISA
@@ -105,8 +112,7 @@
* Higher numeric value == stronger / higher-capability topology. */
#define SIMDID_UARCH_HYBRID_E (1U << 0) /* E-core (efficiency/small) in a hybrid topology */
#define SIMDID_UARCH_HYBRID_P (1U << 1) /* P-core (performance/big) in a hybrid topology */
#define SIMDID_UARCH_SIMD_DUAL \
(1U << 2) /* SIMD is glued/dual (summary: AVX_DUAL or AVX512_IMPL=DUAL) */
#define SIMDID_UARCH_SIMD_DUAL (1U << 2) /* SIMD is glued/dual (summary: AVX_DUAL or AVX512_IMPL=DUAL) */
#endif
// Pack helpers (define locally to avoid missing macros when included standalone)
@@ -239,8 +245,8 @@ INTERNAL uint64_t SN_DECL factorial_simd_sse(int n);
#pragma region dot_product
INTERNAL void FORCEINLINE SN_DECL dot_41_sse(
MAT_KERNEL(float) const *transpose, __m128 const *vector, __m128 *ans);
INTERNAL void FORCEINLINE SN_DECL dot_41_sse(MAT_KERNEL(float) const *transpose,
__m128 const *vector, __m128 *ans);
INTERNAL void SN_DECL dot_41_avx(MAT_KERNEL(float) const *transpose, __m128 const *vector,
__m128 *ans);
INTERNAL void SN_DECL dot_42_sse(MAT_KERNEL(float) const *transpose, __m128 const *vector,
+3 -9
View File
@@ -39,11 +39,6 @@ typedef union uint64_u {
uint32_t u32[2];
} uint64_u;
/* Opaque placeholder used by generic single-kernel dispatch.
* It preserves pointer semantics without pretending every branch shares the
* same concrete MAT_KERNEL(T) type. */
typedef struct sn_mat_kernel_opaque sn_mat_kernel_opaque;
typedef struct mat_kernel mat_kernel;
typedef struct mat_panel mat_panel;
@@ -76,10 +71,9 @@ static_assert(sizeof(matrix_task) == 128, "matrix_parallel_task_package size mis
static_assert(sizeof(matrix_task) == 128, "matrix_parallel_task_package size mismatch");
#endif
typedef void(SN_DECL *UNI_MK_PROC)(matrix_task const *task);
typedef void(SN_DECL *UNI_SK_PROC)(sn_mat_kernel_opaque const *left,
sn_mat_kernel_opaque const *right,
sn_mat_kernel_opaque *restrict ans, uint64_t scalar);
typedef void(SN_DECL *UNI_MK_PROC)(matrix_task *task);
typedef void(SN_DECL *UNI_SK_PROC)(mat_kernel const *left, mat_kernel const *right,
mat_kernel *restrict ans, uint64_t scalar);
typedef void(SN_DECL *VECTORNORMALIZEPROC)(sn_vec_f32 *source, sn_vec_f32 *target);
typedef void(SN_DECL *DOTPROC)(void *transpose, __m128 *vector, __m128 *ans);
@@ -138,7 +138,7 @@ extern __declspec(align(64)) sn_zero_kernel_u64 SN_ZERO_KERNEL;
int col_length, int row_length, \
int col_index, int row_index)
#if 0
/* Declarations for AVX float variant
DECLARE_BUILD_PANEL(avx, float);
DECLARE_BUILD_PANEL(512, float);
@@ -149,6 +149,6 @@ DECLARE_STORE_PANEL(512, float);
DECLARE_BUILD_PANEL(512, double);
DECLARE_STORE_PANEL(512, double);
#endif
/**/
#endif /* SN_MATKERNEL */
#endif /* SN_MATKERNEL */
+17 -19
View File
@@ -2,30 +2,33 @@
#define SN_INTRINSIC_CallCONV_STD
#include "sn_internal.h"
#include "sn_target.h"
#include "sn_intrinsic.h"
#ifndef static_assert
#define static_assert _Static_assert
#endif
#define SN_STD_TARGET_ATTR(T_arch, T_feature) SN_STD_TARGET_ATTR_IMPL(T_arch, T_feature)
#define SN_STD_TARGET_ATTR_IMPL(T_arch, T_feature) SN_X86_TARGET_ATTR_##T_arch##T_feature
#define MK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op) \
T_type##_multi_kernel_proc_##T_op##_##T_arch##_##T_feature
#define GET_MK_PROC_STD(T_type, T_arch, T_feature, T_op) \
MK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op)
((UNI_MK_PROC)MK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op))
#define SN_MK_PROC_DECL(T_type, P_name) INTERNAL void SN_DECL P_name(MAT_TASK(T_type) const *task)
#define SN_MK_PROC_DECL_STD(T_type, T_arch, T_feature, T_op) \
INTERNAL void SN_DECL MK_PROC_NAME_STD(T_type, T_arch, T_feature, \
T_op)(MAT_TASK(T_type) const *task)
#define SN_MK_PROC_DECL_STD(T_type, T_arch, T_feature, T_op) \
INTERNAL NOINLINE SN_STD_TARGET_ATTR(T_arch, T_feature) void SN_DECL \
MK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op)(MAT_TASK(T_type) const *task)
#define SK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op) \
T_type##_single_kernel_proc_##T_op##_##T_arch##_##T_feature
#define GET_SK_PROC_STD(T_type, T_arch, T_feature, T_op) \
SK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op)
#define SN_SK_PROC_DECL_STD(T_type, T_arch, T_feature, T_op) \
INTERNAL void SN_DECL SK_PROC_NAME_STD(T_type, T_arch, T_feature, \
T_op)(sn_mat_kernel_opaque const *left_ptr, \
sn_mat_kernel_opaque const *right_ptr, \
sn_mat_kernel_opaque *restrict ans_ptr, \
uint64_t scalar)
((UNI_SK_PROC)SK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op))
#define SN_SK_PROC_DECL_STD(T_type, T_arch, T_feature, T_op) \
INTERNAL NOINLINE SN_STD_TARGET_ATTR(T_arch, T_feature) void SN_DECL \
SK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op)( \
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
MAT_KERNEL(T_type) *restrict ans, uint64_t scalar)
#define _SN_STD__PROBE_0 0
#define _SN_STD__PROBE_1 1
@@ -103,12 +106,7 @@
_SN_MK_EXPAND_PARAM(param); \
_SN_MK_EXPAND_MEM(mem)
#define __sk_param_std(T) \
typedef MAT_KERNEL(T) SN_MAT_KERNEL_LOCAL; \
SN_MAT_KERNEL_LOCAL const *left = \
(SN_MAT_KERNEL_LOCAL const *)(left_ptr); \
SN_MAT_KERNEL_LOCAL const *right = \
(SN_MAT_KERNEL_LOCAL const *)(right_ptr); \
SN_MAT_KERNEL_LOCAL *restrict ans = \
(SN_MAT_KERNEL_LOCAL *)(ans_ptr)
#define __sk_param_std(T) \
typedef MAT_KERNEL(T) SN_MAT_KERNEL_LOCAL; \
(void)scalar
#endif // !SN_INTRINSIC_PARAM_EXPAND
+10
View File
@@ -76,6 +76,16 @@
#define SN_IS_ARCH(arch) ((SN_ARCH_TARGET) == (arch))
/*
* Per-function ISA selection is required for runtime-dispatched kernels that
* mix multiple x86 feature levels in one build target.
*/
#if defined(__clang__) && ((SN_ARCH_TARGET) == SN_ARCH_X86_64)
#define SN_CLANG_TARGET_ATTR(options) __attribute__((target(options)))
#else
#define SN_CLANG_TARGET_ATTR(options)
#endif
typedef union SIMDID {
uint64_t mask;
char make_byte[8];