From db6cba47d60f92cfb39be1423936b75647800ce7 Mon Sep 17 00:00:00 2001 From: anematode Date: Sat, 6 Jun 2026 10:03:25 +0200 Subject: [PATCH] More loongarch optimizations Passed STC: LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 113120 W: 29094 L: 28674 D: 55352 Ptnml(0-2): 362, 12619, 30248, 12899, 432 https://tests.stockfishchess.org/tests/view/6a1486f7818cacc1db0ac832 closes https://github.com/official-stockfish/Stockfish/pull/6862 No functional change --- src/nnue/nnue_feature_transformer.h | 19 +++++++++++-------- src/nnue/simd.h | 5 +++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/nnue/nnue_feature_transformer.h b/src/nnue/nnue_feature_transformer.h index 2df0454b1..08ebeef84 100644 --- a/src/nnue/nnue_feature_transformer.h +++ b/src/nnue/nnue_feature_transformer.h @@ -308,21 +308,23 @@ class FeatureTransformer { vec_t acc1a = vec_add_16(in1[i + 0], tin1[i + 0]); vec_t acc1b = vec_add_16(in1[i + 1], tin1[i + 1]); - #if defined(USE_NEON) - - // The NEON path relies on unsigned saturation for crelu static_assert(FtMaxVal == 255); + #if defined(USE_NEON) uint16x8_t mul0 = vmull_u8(vqmovun_s16(acc0a), vqmovun_s16(acc1a)); uint16x8_t mul1 = vmull_u8(vqmovun_s16(acc0b), vqmovun_s16(acc1b)); uint8x16x2_t uzp = vuzpq_u8(vreinterpretq_u8_u16(mul0), vreinterpretq_u8_u16(mul1)); - uint8x16_t pab = vshrq_n_u8(uzp.val[1], 1); - packed[k] = out[j + k] = reinterpret_cast(pab); + uint8x16_t pab = vshrq_n_u8(uzp.val[1], 1); + vec_t result = reinterpret_cast(pab); + #elif defined(USE_LSX) || defined(USE_LASX) + vec_t pa = vec_packus_16(acc0a, acc0b); + vec_t pb = vec_packus_16(acc1a, acc1b); + vec_t hi = vec_mulhi_8(pa, pb); + vec_t result = vec_srli_8(hi, 1); #else - vec_t sum0a = vec_slli_16(vec_max_16(vec_min_16(acc0a, FtMax), Zero), shift); vec_t sum0b = vec_slli_16(vec_max_16(vec_min_16(acc0b, FtMax), Zero), shift); vec_t sum1a = vec_min_16(acc1a, FtMax); @@ -331,9 +333,10 @@ class FeatureTransformer { vec_t pa = vec_mulhi_16(sum0a, sum1a); vec_t pb = vec_mulhi_16(sum0b, sum1b); - packed[k] = out[j + k] = vec_packus_16(pa, pb); - + vec_t result = vec_packus_16(pa, pb); #endif + + packed[k] = out[j + k] = result; } cursor.record2(packed[0], packed[1]); diff --git a/src/nnue/simd.h b/src/nnue/simd.h index c9c585b50..df2a36db3 100644 --- a/src/nnue/simd.h +++ b/src/nnue/simd.h @@ -282,6 +282,8 @@ inline __m256i lasx_packus_32(__m256i a, __m256i b) { #define vec_zero_psqt() __lasx_xvldi(0) #define vec_nnz(a) lasx_vec_nnz(a) #define vec_convert_8_16(a) lasx_cvtepi8_epi16(a) + #define vec_mulhi_8 __lasx_xvmuh_bu + #define vec_srli_8 __lasx_xvsrli_b #define vec128_zero __lsx_vldi(0) #define vec128_set_16(a) __lsx_vreplgr2vr_h(a) @@ -368,6 +370,9 @@ inline __m128i vec_convert_8_16(std::uint64_t x) { return __lsx_vsllwil_h_b(v, 0); } + #define vec_mulhi_8 __lsx_vmuh_bu + #define vec_srli_8 __lsx_vsrli_b + #define vec128_zero __lsx_vldi(0) #define vec128_set_16(a) __lsx_vreplgr2vr_h(a) #define vec128_load(a) (*(a))