mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 12:47:08 +00:00
Shave some instructions off a hot loop in affine transform
On x86, GCC generates highly suboptimal code for this loop in its old form, about 2x as many instructions as necessary. This decreases throughput especially in an SMT setting. Clang does a better job but this change still has some improvement. Note that the std::ptrdiff_t type is not optional; using an unsigned type brings back the bad assembly. (Not sure why, but it seems reliable on all the GCC versions I tested.) passed STC: LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 44672 W: 11841 L: 11527 D: 21304 Ptnml(0-2): 165, 4625, 12415, 4993, 138 https://tests.stockfishchess.org/tests/view/68d8111efa806e2e8393b10e closes https://github.com/official-stockfish/Stockfish/pull/6331 No functional change
This commit is contained in:
committed by
Joost VandeVondele
parent
4f4f78f86e
commit
9b164d9520
@@ -243,6 +243,7 @@ Thanar2
|
|||||||
thaspel
|
thaspel
|
||||||
theo77186
|
theo77186
|
||||||
TierynnB
|
TierynnB
|
||||||
|
Timothy Herchen (anematode)
|
||||||
Ting-Hsuan Huang (fffelix-huang)
|
Ting-Hsuan Huang (fffelix-huang)
|
||||||
Tobias Steinmann
|
Tobias Steinmann
|
||||||
Tomasz Sobczyk (Sopel97)
|
Tomasz Sobczyk (Sopel97)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#define NNUE_LAYERS_AFFINE_TRANSFORM_SPARSE_INPUT_H_INCLUDED
|
#define NNUE_LAYERS_AFFINE_TRANSFORM_SPARSE_INPUT_H_INCLUDED
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@@ -287,12 +288,18 @@ class AffineTransformSparseInput {
|
|||||||
for (IndexType k = 0; k < NumRegs; ++k)
|
for (IndexType k = 0; k < NumRegs; ++k)
|
||||||
acc[k] = biasvec[k];
|
acc[k] = biasvec[k];
|
||||||
|
|
||||||
for (IndexType j = 0; j < count; ++j)
|
auto* start = nnz;
|
||||||
|
auto* end = nnz + count;
|
||||||
|
|
||||||
|
// convince GCC to not do weird pointer arithmetic in the following loop
|
||||||
|
const std::int8_t* weights_cp = weights;
|
||||||
|
|
||||||
|
while (start < end)
|
||||||
{
|
{
|
||||||
const auto i = nnz[j];
|
const std::ptrdiff_t i = *start;
|
||||||
|
start++;
|
||||||
const invec_t in = vec_set_32(input32[i]);
|
const invec_t in = vec_set_32(input32[i]);
|
||||||
const auto col =
|
const auto col = (const invec_t*) (&weights_cp[i * OutputDimensions * ChunkSize]);
|
||||||
reinterpret_cast<const invec_t*>(&weights[i * OutputDimensions * ChunkSize]);
|
|
||||||
for (IndexType k = 0; k < NumRegs; ++k)
|
for (IndexType k = 0; k < NumRegs; ++k)
|
||||||
vec_add_dpbusd_32(acc[k], in, col[k]);
|
vec_add_dpbusd_32(acc[k], in, col[k]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user