/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
- Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
+ Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
{
const IndexType offset = HalfDimensions * p;
const auto out = reinterpret_cast<int8x8_t*>(&output[offset]);
- for (IndexType j = 0; j < NumChunks; ++j)
+
+ constexpr IndexType UnrollFactor = 16;
+ static_assert(UnrollFactor % UnrollFactor == 0);
+ for (IndexType j = 0; j < NumChunks; j += UnrollFactor)
{
- int16x8_t sum = reinterpret_cast<const int16x8_t*>(accumulation[perspectives[p]])[j];
- out[j] = vmax_s8(vqmovn_s16(sum), Zero);
+ int16x8_t sums[UnrollFactor];
+ for (IndexType i = 0; i < UnrollFactor; ++i)
+ sums[i] = reinterpret_cast<const int16x8_t*>(accumulation[perspectives[p]])[j+i];
+
+ for (IndexType i = 0; i < UnrollFactor; ++i)
+ out[j+i] = vmax_s8(vqmovn_s16(sums[i]), Zero);
}
}
return psqt;
// That might depend on the feature set and generally relies on the
// feature set's update cost calculation to be correct and never
// allow updates with more added/removed features than MaxActiveDimensions.
- using IndexList = ValueList<IndexType, FeatureSet::MaxActiveDimensions>;
#ifdef VECTOR
// Gcc-10.2 unnecessarily spills AVX2 registers if this array
// of the estimated gain in terms of features to be added/subtracted.
StateInfo *st = pos.state(), *next = nullptr;
int gain = FeatureSet::refresh_cost(pos);
- while (st->accumulator.state[perspective] == EMPTY)
+ while (st->previous && !st->accumulator.computed[perspective])
{
// This governs when a full feature refresh is needed and how many
// updates are better than just one full refresh.
st = st->previous;
}
- if (st->accumulator.state[perspective] == COMPUTED)
+ if (st->accumulator.computed[perspective])
{
if (next == nullptr)
return;
// Gather all features to be updated.
const Square ksq = pos.square<KING>(perspective);
- IndexList removed[2], added[2];
+ FeatureSet::IndexList removed[2], added[2];
FeatureSet::append_changed_indices(
- ksq, next, perspective, removed[0], added[0]);
+ ksq, next->dirtyPiece, perspective, removed[0], added[0]);
for (StateInfo *st2 = pos.state(); st2 != next; st2 = st2->previous)
FeatureSet::append_changed_indices(
- ksq, st2, perspective, removed[1], added[1]);
+ ksq, st2->dirtyPiece, perspective, removed[1], added[1]);
// Mark the accumulators as computed.
- next->accumulator.state[perspective] = COMPUTED;
- pos.state()->accumulator.state[perspective] = COMPUTED;
+ next->accumulator.computed[perspective] = true;
+ pos.state()->accumulator.computed[perspective] = true;
// Now update the accumulators listed in states_to_update[], where the last element is a sentinel.
StateInfo *states_to_update[3] =
{
// Refresh the accumulator
auto& accumulator = pos.state()->accumulator;
- accumulator.state[perspective] = COMPUTED;
- IndexList active;
+ accumulator.computed[perspective] = true;
+ FeatureSet::IndexList active;
FeatureSet::append_active_indices(pos, perspective, active);
#ifdef VECTOR