Вы очевидно как и Владимирович не понимаете о чем идет речь.
Скорее вы не очень хорошо владеете тем как работают базы данных и как на них достигаются тысячи TPS даже на запись, а тут примитивнейшее чтение очень коротких и не изменяющихся записей.
Обращение к таблице, когда осталось только 7 фигур очевидно ускорит и улучшит игру, а вот обращение к таблицам при расчете вариантов издалека уже не обязано усиливать игру движка.
О майн Готт? Дык кто об этом говорит-то?
Просто когда нода доходит до конкретной позиции, то если N<=6 ( или N<=7) мы обрываем дальнейший расчет и берем оценку из базы вместо расчетьа и оценки десятков тысяч позиций, (возможна другая цифра, но тоже большая) получающихся из этой вершины графа.
Ферштеен? PP wrote:
Поскольку различные 7 фигурки будут возникать при расчете издалека, неизбежно придется постоянно обращаться к диску, Вы очевидно как и Владимирович не понимаете о чем идет речь.
Дистрибутив 48Гб занимает. Даже если в распакованом виде это и терабайты занимает это не играет никакой рояли. В реальной партии и гигабайта полезной информации не потребуется. Это все легко влезает в кэш персоналки не говоря уже про мощные рабочие станции и сервера.
Однозначно. Первые же обращения поднимут в кэш страницы с оценками для получающегося соотношения фигур при переходе в эндшпиль и все остальные запросы будут долбить по памяти. Собственно такие структурированные не меняющиеся данные крайне быстро и с диска прочитаются, поскольку индексирование никто не отменял.
Однозначно. Первые же обращения поднимут в кэш страницы с оценками для получающегося соотношения фигур при переходе в эндшпиль и все остальные запросы будут долбить по памяти.
Я думаю, что даже не это главное.
Вот нарисовал для ясности очень урезанную схему
Слева вариант таблиц. В красной точке весь расчет заканчивается
Справа расчет. В каждой точке нужно
А. Найти все ходы кандидаты.
Б. Построить позиции после каждого полухода
В. Оценить их
Г. Провести альфа-бета отсечение мусора
Д. Вернуться к п.А для всего набора отфильтрованных позиций
Е. Повторить цикл до готовности, которая хз еще когда наступит
А.
Б.
В.
.............
И нас хотят убедить, что одно обращение к диску к БД по индексу, которое занимает в левом случае миллисекунды, если даже не юзать кэш, дольше чем вся эта бодяга справа?
Это бред, как я это называю.
Просто когда нода доходит до конкретной позиции, то если N<=6 ( или N<=7) мы обрываем дальнейший расчет и берем оценку из базы вместо расчетьа и оценки десятков тысяч позиций
Мне кажется, что тут уже надо как минимум хорошо разбираться в конкретных деталях. Да, если я на глубине 2 дополз до базы, то действительно смогу скорее всего сэкономить время, но если мы дошли до базы на глубине близкой к концу расчета, то использование базы на несколько порядков замедлит алгоритм и при этом далеко не факт, что база как то принципиально улучшит оценку. Большинство позиций правильно оцениваются без всяких баз. Ув. Александр привел тут конкретную информацию, подтверждающую наличие специальных настроек для использования баз. Уже само наличие этих настроек как бе показывает нетривиальность вопроса.
Схема красивая, но неполная. Вы нарисуйте ситуацию, когда обращение к таблице происходит в конце расчета. У Вас будет много красныж точек вместо 1 - 10 вызовов очень быстрой ОФ. Кеширование, про которое нам рассказывает Руслан будет зависеть от похожести окончаний возникающиж в разных ветках. Судя по тому что пишут програмеры избегать обращение к диску не удается.
Мне кажется, что тут уже надо как минимум хорошо разбираться в конкретных деталях. Да, если я на глубине 2 дополз до базы, то действительно смогу скорее всего сэкономить время, но если мы дошли до базы на глубине близкой к концу расчета, то использование базы на несколько порядков замедлит алгоритм и при этом далеко не факт, что база как то принципиально улучшит оценку.
О Майн готт
Запускайте свою пукалку
R7/6k1/P7/8/8/8/6K1/r7 w - - 1 1
У меня Вобла 8 на CoreI7 уже минуту показывает +3... О, уже +2.85.... Идет 76 полуход....
А старенькая Рыбка сразу, МГНОВЕННО, говорит, что рыба =
И это уже для 5-фигурок.
Вы вообще подумали бы сначала, прежде чем такое нам говорить
Six piece positions can be even harder, such as rook versus bishop and two pawns, queen versus rook and two pawns (think of the numerous fortress situations), and the list goes on. The problem is that some of the files of the more difficult positions can take up one or even two gigabytes a piece. If the engine is accessing more than one due to the various situations it is considering, it can cause the computer to start reading the hard disk non-stop, which in turn can result in significant slowdowns.
А теперь проэкстраполируем на 7 фигур. Надо будет десятки гигов если не больше загружать и выгружать.
Если Вы будете продолжать говорить, что это все (с циклом внутри, т.е цикл минимум двойной) страшно быстрее, чем слазить в файл, в известное место, я очень огорчусь Вашим познаниям в этой области.
template<Tracing T> template<Color Us, PieceType Pt>
Score Evaluation<T>::evaluate_pieces() {
const Color Them = (Us == WHITE ? BLACK : WHITE);
const Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
: Rank5BB | Rank4BB | Rank3BB);
const Square* pl = pos.squares<Pt>(Us);
Bitboard b, bb;
Square s;
Score score = SCORE_ZERO;
attackedBy[Us][Pt] = 0;
while ((s = *pl++) != SQ_NONE)
{
// Find attacked squares, including x-ray attacks for bishops and rooks
b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(Us, QUEEN))
: Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(Us, ROOK, QUEEN))
: pos.attacks_from<Pt>(s);
if (pos.pinned_pieces(Us) & s)
b &= LineBB[pos.square<KING>(Us)][s];
attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
attackedBy[Us][ALL_PIECES] |= attackedBy[Us][Pt] |= b;
if (b & kingRing[Them])
{
kingAttackersCount[Us]++;
kingAttackersWeight[Us] += KingAttackWeights[Pt];
kingAdjacentZoneAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
}
int mob = popcount(b & mobilityArea[Us]);
mobility[Us] += MobilityBonus[Pt - 2][mob];
// Bonus for this piece as a king protector
score += KingProtector[Pt - 2] * distance(s, pos.square<KING>(Us));
if (Pt == BISHOP || Pt == KNIGHT)
{
// Bonus for outpost squares
bb = OutpostRanks & ~pe->pawn_attacks_span(Them);
if (bb & s)
score += Outpost[Pt == BISHOP][!!(attackedBy[Us][PAWN] & s)] * 2;
else
{
bb &= b & ~pos.pieces(Us);
if (bb)
score += Outpost[Pt == BISHOP][!!(attackedBy[Us][PAWN] & bb)];
}
// Bonus when behind a pawn
if ( relative_rank(Us, s) < RANK_5
&& (pos.pieces(PAWN) & (s + pawn_push(Us))))
score += MinorBehindPawn;
if (Pt == BISHOP)
{
// Penalty for pawns on the same color square as the bishop
score -= BishopPawns * pe->pawns_on_same_color_squares(Us, s);
// Bonus for bishop on a long diagonal without pawns in the center
if ( (LongDiagonals & s)
&& !(attackedBy[Them][PAWN] & s)
&& !(Center & PseudoAttacks[BISHOP][s] & pos.pieces(PAWN)))
score += LongRangedBishop;
}
// An important Chess960 pattern: A cornered bishop blocked by a friendly
// pawn diagonally in front of it is a very serious problem, especially
// when that pawn is also blocked.
if ( Pt == BISHOP
&& pos.is_chess960()
&& (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
{
Square d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
if (pos.piece_on(s + d) == make_piece(Us, PAWN))
score -= !pos.empty(s + d + pawn_push(Us)) ? TrappedBishopA1H1 * 4
: pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? TrappedBishopA1H1 * 2
: TrappedBishopA1H1;
}
}
if (Pt == ROOK)
{
// Bonus for aligning with enemy pawns on the same rank/file
if (relative_rank(Us, s) >= RANK_5)
score += RookOnPawn * popcount(pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s]);
// Bonus when on an open or semi-open file
if (pe->semiopen_file(Us, file_of(s)))
score += RookOnFile[!!pe->semiopen_file(Them, file_of(s))];
// Penalty when trapped by the king, even more if the king cannot castle
else if (mob <= 3)
{
Square ksq = pos.square<KING>(Us);
if ( ((file_of(ksq) < FILE_E) == (file_of(s) < file_of(ksq)))
&& !pe->semiopen_side(Us, file_of(ksq), file_of(s) < file_of(ksq)))
score -= (TrappedRook - make_score(mob * 22, 0)) * (1 + !pos.can_castle(Us));
}
}
if (Pt == QUEEN)
{
// Penalty if any relative pin or discovered attack against the queen
Bitboard pinners;
if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, pinners))
score -= WeakQueen;
}
}
if (T)
Trace::add(Pt, Us, score);
return score;
}
// evaluate_king() assigns bonuses and penalties to a king of a given color
template<Tracing T> template<Color Us>
Score Evaluation<T>::evaluate_king() {
const Color Them = (Us == WHITE ? BLACK : WHITE);
const Square Up = (Us == WHITE ? NORTH : SOUTH);
const Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
: AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
const Square ksq = pos.square<KING>(Us);
Bitboard kingOnlyDefended, undefended, b, b1, b2, safe, other;
int kingDanger;
// King shelter and enemy pawns storm
Score score = pe->king_safety<Us>(pos, ksq);
// Main king safety evaluation
if (kingAttackersCount[Them] > (1 - pos.count<QUEEN>(Them)))
{
// Find the attacked squares which are defended only by our king...
kingOnlyDefended = attackedBy[Them][ALL_PIECES]
& attackedBy[Us][KING]
& ~attackedBy2[Us];
// ... and those which are not defended at all in the larger king ring
undefended = attackedBy[Them][ALL_PIECES]
& ~attackedBy[Us][ALL_PIECES]
& kingRing[Us]
& ~pos.pieces(Them);
// Initialize the 'kingDanger' variable, which will be transformed
// later into a king danger score. The initial value is based on the
// number and types of the enemy's attacking pieces, the number of
// attacked and weak squares around our king, the absence of queen and
// the quality of the pawn shelter (current 'score' value).
kingDanger = kingAttackersCount[Them] * kingAttackersWeight[Them]
+ 102 * kingAdjacentZoneAttacksCount[Them]
+ 191 * popcount(kingOnlyDefended | undefended)
+ 143 * !!pos.pinned_pieces(Us)
- 848 * !pos.count<QUEEN>(Them)
- 9 * mg_value(score) / 8
+ 40;
// Analyse the safe enemy's checks which are possible on next move
safe = ~pos.pieces(Them);
safe &= ~attackedBy[Us][ALL_PIECES] | (kingOnlyDefended & attackedBy2[Them]);
b1 = pos.attacks_from< ROOK>(ksq);
b2 = pos.attacks_from<BISHOP>(ksq);
// Enemy queen safe checks
if ((b1 | b2) & attackedBy[Them][QUEEN] & safe)
kingDanger += QueenCheck;
// For minors and rooks, also consider the square safe if attacked twice,
// and only defended by our queen.
safe |= attackedBy2[Them]
& ~(attackedBy2[Us] | pos.pieces(Them))
& attackedBy[Us][QUEEN];
// Some other potential checks are also analysed, even from squares
// currently occupied by the opponent own pieces, as long as the square
// is not attacked by our pawns, and is not occupied by a blocked pawn.
other = ~( attackedBy[Us][PAWN]
| (pos.pieces(Them, PAWN) & shift<Up>(pos.pieces(PAWN))));
// Enemy rooks safe and other checks
if (b1 & attackedBy[Them][ROOK] & safe)
kingDanger += RookCheck;
else if (b1 & attackedBy[Them][ROOK] & other)
score -= OtherCheck;
// Enemy bishops safe and other checks
if (b2 & attackedBy[Them][BISHOP] & safe)
kingDanger += BishopCheck;
else if (b2 & attackedBy[Them][BISHOP] & other)
score -= OtherCheck;
// Enemy knights safe and other checks
b = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
if (b & safe)
kingDanger += KnightCheck;
else if (b & other)
score -= OtherCheck;
// Transform the kingDanger units into a Score, and substract it from the evaluation
if (kingDanger > 0)
score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
}
// King tropism: firstly, find squares that opponent attacks in our king flank
File kf = file_of(ksq);
b = attackedBy[Them][ALL_PIECES] & KingFlank[kf] & Camp;
assert(((Us == WHITE ? b << 4 : b >> 4) & b) == 0);
assert(popcount(Us == WHITE ? b << 4 : b >> 4) == popcount(b));
// Secondly, add the squares which are attacked twice in that flank and
// which are not defended by our pawns.
b = (Us == WHITE ? b << 4 : b >> 4)
| (b & attackedBy2[Them] & ~attackedBy[Us][PAWN]);
score -= CloseEnemies * popcount(b);
// Penalty when our king is on a pawnless flank
if (!(pos.pieces(PAWN) & KingFlank[kf]))
score -= PawnlessFlank;
if (T)
Trace::add(KING, Us, score);
return score;
}
// evaluate_threats() assigns bonuses according to the types of the attacking
// and the attacked pieces.
template<Tracing T> template<Color Us>
Score Evaluation<T>::evaluate_threats() {
const Color Them = (Us == WHITE ? BLACK : WHITE);
const Square Up = (Us == WHITE ? NORTH : SOUTH);
const Square Left = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
const Square Right = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
const Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
Bitboard b, weak, defended, stronglyProtected, safeThreats;
Score score = SCORE_ZERO;
// Non-pawn enemies attacked by a pawn
weak = (pos.pieces(Them) ^ pos.pieces(Them, PAWN)) & attackedBy[Us][PAWN];
if (weak)
{
b = pos.pieces(Us, PAWN) & ( ~attackedBy[Them][ALL_PIECES]
| attackedBy[Us][ALL_PIECES]);
safeThreats = (shift<Right>(b) | shift<Left>(b)) & weak;
score += ThreatBySafePawn * popcount(safeThreats);
if (weak ^ safeThreats)
score += ThreatByHangingPawn;
}
// Squares strongly protected by the opponent, either because they attack the
// square with a pawn, or because they attack the square twice and we don't.
stronglyProtected = attackedBy[Them][PAWN]
| (attackedBy2[Them] & ~attackedBy2[Us]);
// Non-pawn enemies, strongly protected
defended = (pos.pieces(Them) ^ pos.pieces(Them, PAWN))
& stronglyProtected;
// Enemies not strongly protected and under our attack
weak = pos.pieces(Them)
& ~stronglyProtected
& attackedBy[Us][ALL_PIECES];
// Add a bonus according to the kind of attacking pieces
if (defended | weak)
{
b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
while (b)
{
Square s = pop_lsb(&b);
score += ThreatByMinor[type_of(pos.piece_on(s))];
if (type_of(pos.piece_on(s)) != PAWN)
score += ThreatByRank * (int)relative_rank(Them, s);
}
b = (pos.pieces(Them, QUEEN) | weak) & attackedBy[Us][ROOK];
while (b)
{
Square s = pop_lsb(&b);
score += ThreatByRook[type_of(pos.piece_on(s))];
if (type_of(pos.piece_on(s)) != PAWN)
score += ThreatByRank * (int)relative_rank(Them, s);
}
score += Hanging * popcount(weak & ~attackedBy[Them][ALL_PIECES]);
b = weak & attackedBy[Us][KING];
if (b)
score += ThreatByKing[more_than_one(b)];
}
// Bonus for opponent unopposed weak pawns
if (pos.pieces(Us, ROOK, QUEEN))
score += WeakUnopposedPawn * pe->weak_unopposed(Them);
// Find squares where our pawns can push on the next move
b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
// Keep only the squares which are not completely unsafe
b &= ~attackedBy[Them][PAWN]
& (attackedBy[Us][ALL_PIECES] | ~attackedBy[Them][ALL_PIECES]);
// Add a bonus for each new pawn threats from those squares
b = (shift<Left>(b) | shift<Right>(b))
& pos.pieces(Them)
& ~attackedBy[Us][PAWN];
score += ThreatByPawnPush * popcount(b);
if (T)
Trace::add(THREAT, Us, score);
return score;
}
// evaluate_passed_pawns() evaluates the passed pawns and candidate passed
// pawns of the given color.
template<Tracing T> template<Color Us>
Score Evaluation<T>::evaluate_passed_pawns() {
const Color Them = (Us == WHITE ? BLACK : WHITE);
const Square Up = (Us == WHITE ? NORTH : SOUTH);
Bitboard b, bb, squaresToQueen, defendedSquares, unsafeSquares;
Score score = SCORE_ZERO;
b = pe->passed_pawns(Us);
while (b)
{
Square s = pop_lsb(&b);
assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
bb = forward_file_bb(Us, s) & (attackedBy[Them][ALL_PIECES] | pos.pieces(Them));
score -= HinderPassedPawn * popcount(bb);
int r = relative_rank(Us, s) - RANK_2;
int rr = r * (r - 1);
Value mbonus = Passed[MG][r], ebonus = Passed[EG][r];
if (rr)
{
Square blockSq = s + Up;
// Adjust bonus based on the king's proximity
ebonus += distance(pos.square<KING>(Them), blockSq) * 5 * rr
- distance(pos.square<KING>( Us), blockSq) * 2 * rr;
// If blockSq is not the queening square then consider also a second push
if (relative_rank(Us, blockSq) != RANK_8)
ebonus -= distance(pos.square<KING>(Us), blockSq + Up) * rr;
// If the pawn is free to advance, then increase the bonus
if (pos.empty(blockSq))
{
// If there is a rook or queen attacking/defending the pawn from behind,
// consider all the squaresToQueen. Otherwise consider only the squares
// in the pawn's path attacked or occupied by the enemy.
defendedSquares = unsafeSquares = squaresToQueen = forward_file_bb(Us, s);
bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN) & pos.attacks_from<ROOK>(s);
if (!(pos.pieces(Us) & bb))
defendedSquares &= attackedBy[Us][ALL_PIECES];
if (!(pos.pieces(Them) & bb))
unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
// If there aren't any enemy attacks, assign a big bonus. Otherwise
// assign a smaller bonus if the block square isn't attacked.
int k = !unsafeSquares ? 18 : !(unsafeSquares & blockSq) ? 8 : 0;
// If the path to the queen is fully defended, assign a big bonus.
// Otherwise assign a smaller bonus if the block square is defended.
if (defendedSquares == squaresToQueen)
k += 6;
else if (defendedSquares & blockSq)
k += 4;
mbonus += k * rr, ebonus += k * rr;
}
else if (pos.pieces(Us) & blockSq)
mbonus += rr + r * 2, ebonus += rr + r * 2;
} // rr != 0
// Scale down bonus for candidate passers which need more than one
// pawn push to become passed or have a pawn in front of them.
if (!pos.pawn_passed(Us, s + Up) || (pos.pieces(PAWN) & forward_file_bb(Us, s)))
mbonus /= 2, ebonus /= 2;
score += make_score(mbonus, ebonus) + PassedFile[file_of(s)];
}
if (T)
Trace::add(PASSED, Us, score);
return score;
}
А как Вы думаете прога работает? До конца считает штоле? Тогда ОФ была бы нам не нужна совсем. На глубине эн мы обрываем расчет и возвращаем некое значение ОФ или лезем в таблицы и тратим на это в тысячу раз больше времени.Vladimirovich wrote:
Если я оборву анализ на позиции выше с оценкой +3, я могу просто выбрать неправильный путь
Можете, вопрос как часто и какой ценой Вам будет нужна точная оценка на практике.Vladimirovich wrote:
В этом эндшпиле, напомню, каждая деталь имеет место
Нет ну шоб вас с Шиповым обрадовать можно много чего засунуть, можно саму ОФ значительно усложнить, добавить кучу специализаций. Я пишу о практической силе игры, а не о самоцели лишить вас с Шиповым возможности критиковать железяки.
Not all computers will have any issues, so if you do not, then do not concern yourself any further. If you do, however, there are a variety of ways to resolve this issue, so that you need not forego on this great tool.
Откуда эта оценка или у Вас точность плюс минус два порядка как выше?
А вы попробуйте подумать сами. Сколько разных позиций с 7ю фигурами в момент размена 8й фигуры у вас в партии может возникнуть и сколько посчитанные оценки для них занимать могут? А то работаете таблицей Налимова в дискуссии, оперируете вычитаной где-то цифирькой а движок то простаивает.
Очевидно, что Вы вслед за Русланом перешли на тон, который мне неприятен.
Извините.
Просто я не вижу с Вашей стороны даже попытки меня понять.
Я Вам привожу конкретные аргументы, а в ответ вижу абстрактные гипотезы и предположения
Мне это также неприятно
. Дальше обсуждайте друг сдругом, какие Вы баальшие спецы в БД.
Не очень большие, но учитывая, что не одна пятилетка потрачена на разработку софта работающего с БД, достаточно большие, ув. РР чтобы знать основы, как устроены индексы, чтение с диска и т.п.. Можете поверить на слово, тормозить будет ровно первое обращение в виду того что инициализируется много внутренних объектов, раскручиваются шпиндели дисков. Потом все будет летать мухой...
Мне кажется, что тут уже надо как минимум хорошо разбираться в конкретных деталях. Да, если я на глубине 2 дополз до базы, то действительно смогу скорее всего сэкономить время, но если мы дошли до базы на глубине близкой к концу расчета, то использование базы на несколько порядков замедлит алгоритм
Замедлит существенно один раз. Остальные переходы будут случаться так редко и однообразно, что никто и не заметит. Никто не мешает особо мнительным таблицы Налимова подключать не на глубине N а на 0.7N, если так уж важно как движок играет эндшпиля в пулю по минутке. Но скорее всего он проиграет движку который пользуется таблицами вовсю просто из-за кривой безтабличной оценки. Тупо не те ходы будет выбирать.
Насчет скоростей хочется сказать.
Если движок начинает плотно работать с базой и обращений к ней тысячи (например, к 6-фигуркам из начальной 10-фигурной позиции), то нет никакой уверенности, что кусок базы, прочтенный ранее, обязательно будет содержать ответ на новый запрос. Т.е. дисковые операции сохраняются (с учетом индексов), а они порядка на 3 медленнее счета ОФ из процессорного кэша. Окончательную оценку и возможную перестройку всего графа придется сильно подождать
Именно поэтому в движках и появляются настраиваемые параметры, отвечающие за работу с эндшпильной базой (настройки Стокфиша):
Increasing the "SyzygyProbeDepth" option lets the engine probe less aggressively. Set this option to a higher value if you experience too much slowdown (in terms of nps) due to TB probing.
Насчет скоростей хочется сказать.
Если движок начинает плотно работать с базой и обращений к ней тысячи (например, к 6-фигуркам из начальной 10-фигурной позиции), то нет никакой уверенности, что кусок базы, прочтенный ранее, обязательно будет содержать ответ на новый запрос. Т.е. дисковые операции сохраняются (с учетом индексов), а они порядка на 3 медленнее счета ОФ из процессорного кэша. Окончательную оценку и возможную перестройку всего графа придется сильно подождать
Именно поэтому в движках и появляются настраиваемые параметры, отвечающие за работу с эндшпильной базой (настройки Стокфиша):
Increasing the "SyzygyProbeDepth" option lets the engine probe less aggressively. Set this option to a higher value if you experience too much slowdown (in terms of nps) due to TB probing.
7 фигурные то есть недоступны, база порядка 1.5 терабайта. Это надо какие-то очень экзотические позы находить чтобы они проваливались в 6 фигурки в таком огромном разнообразии вариантов, что число разных позиций где съедают 7ю фигуру за 1000 000 переваливало например.
Пусть 2-3 десятка байт на оценку в таблице, 20-30М байт, пусть они не рядом, надо 50М в кэш поднять.
Это секунды для винтов обычных не SSD. Если вы играете не в пулю по минуте, то это фигня.
Но я не особо верю в такие позициии с миллионом уникальных взятий 7й фигуры. Все фигуры которые могут быть съедены они изначально при 10 фигурах на каких-то полях стоят, они должны хаотично бегать по всей доске, чтобы их в самых разных позах убивали. Такое не имеет смысла в реальной игре, движок такое дерево не будет строить.
7 фигурные то есть недоступны, база порядка 1.5 терабайта. Это надо какие-то очень экзотические позы находить чтобы они проваливались в 6 фигурки в таком огромном разнообразии вариантов, что число разных позиций где съедают 7ю фигуру за 1000 000 переваливало например.
А разве есть семифигурные базы не платные? Или по ftp планируете к ним обращаться?
Чтобы попасть из 10-фигурной позиции в 6-фигурную достаточно всего 4 фигуры съесть. Что возможно в ФВ