mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 12:47:08 +00:00
Neon dotprod speedup in sparse-input affine transform
Also apply VNNI accumulator splitting strategy to NEON dotprod. Speedup measured locally with profile-build, apple-silicon M3 Pro: ``` Result of 20 runs ================== base (...kfish-master) = 1582485 +/- 12985 test (...parse-affine) = 1605204 +/- 13801 diff = +22720 +/- 1212 speedup = +0.0144 P(speedup > 0) = 1.0000 CPU: 11 x arm Hyperthreading: off ``` Passed STC: https://tests.stockfishchess.org/tests/view/69c04c71f690a4b7f5fb0cde LLR: 2.95 (-2.94,2.94) <0.00,2.00> Total: 80576 W: 20748 L: 20391 D: 39437 Ptnml(0-2): 161, 8472, 22658, 8843, 154 closes https://github.com/official-stockfish/Stockfish/pull/6682 No functional change
This commit is contained in:
@@ -288,7 +288,7 @@ class AffineTransformSparseInput {
|
|||||||
// If we're using high-latency dot product instructions, split the accumulators
|
// If we're using high-latency dot product instructions, split the accumulators
|
||||||
// to create 3 separate dependency chains and merge at the end
|
// to create 3 separate dependency chains and merge at the end
|
||||||
constexpr IndexType NumRegs =
|
constexpr IndexType NumRegs =
|
||||||
#if defined(USE_VNNI)
|
#if defined(USE_VNNI) || defined(USE_NEON_DOTPROD)
|
||||||
3 * NumAccums;
|
3 * NumAccums;
|
||||||
#else
|
#else
|
||||||
NumAccums;
|
NumAccums;
|
||||||
@@ -309,9 +309,14 @@ class AffineTransformSparseInput {
|
|||||||
|
|
||||||
// convince GCC to not do weird pointer arithmetic in the following loop
|
// convince GCC to not do weird pointer arithmetic in the following loop
|
||||||
const std::int8_t* weights_cp = weights;
|
const std::int8_t* weights_cp = weights;
|
||||||
#if defined(USE_VNNI)
|
#if defined(USE_VNNI) || defined(USE_NEON_DOTPROD)
|
||||||
|
#if defined(USE_VNNI)
|
||||||
for (IndexType k = NumAccums; k < NumRegs; ++k)
|
for (IndexType k = NumAccums; k < NumRegs; ++k)
|
||||||
acc[k] = vec_zero();
|
acc[k] = vec_zero();
|
||||||
|
#else
|
||||||
|
for (IndexType k = NumAccums; k < NumRegs; ++k)
|
||||||
|
acc[k] = vdupq_n_s32(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
while (start < end - 2)
|
while (start < end - 2)
|
||||||
{
|
{
|
||||||
@@ -337,8 +342,13 @@ class AffineTransformSparseInput {
|
|||||||
vec_add_dpbusd_32(acc[k + 2 * NumAccums], in2, col2[k]);
|
vec_add_dpbusd_32(acc[k + 2 * NumAccums], in2, col2[k]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if defined(USE_VNNI)
|
||||||
for (IndexType k = 0; k < NumAccums; ++k)
|
for (IndexType k = 0; k < NumAccums; ++k)
|
||||||
acc[k] = vec_add_32(vec_add_32(acc[k], acc[k + NumAccums]), acc[k + 2 * NumAccums]);
|
acc[k] = vec_add_32(vec_add_32(acc[k], acc[k + NumAccums]), acc[k + 2 * NumAccums]);
|
||||||
|
#else
|
||||||
|
for (IndexType k = 0; k < NumAccums; ++k)
|
||||||
|
acc[k] = vaddq_s32(vaddq_s32(acc[k], acc[k + NumAccums]), acc[k + 2 * NumAccums]);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
while (start < end)
|
while (start < end)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user