Skip to content

Commit ca04e6f

Browse files
memory optimization
1 parent 35af125 commit ca04e6f

File tree

6 files changed

+44
-77
lines changed

6 files changed

+44
-77
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ add_subdirectory(src)
2626
target_link_libraries(ChessEngine src)
2727

2828
if (NOT WASM)
29-
# add_subdirectory(tests)
29+
add_subdirectory(tests)
3030
endif ()
3131

3232
if (WASM)

src/Move.h

+9-9
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ namespace Moves {
2323
};
2424

2525
struct Move {
26-
int_fast8_t start;
27-
int_fast8_t end;
28-
Type promotionType;
29-
MoveFlag flag;
30-
Color player;
26+
int8_t start : 8;
27+
int8_t end : 8;
28+
Type promotionType : 4;
29+
MoveFlag flag : 4;
30+
Color player : 1;
3131

3232
bool operator==(const Move&other) const {
3333
return (start == other.start && end == other.end && promotionType == other.promotionType &&
@@ -54,7 +54,7 @@ namespace Moves {
5454

5555
constexpr Move NULL_MOVE = Move{0, 0, Pieces::EMPTY, QUIET, Color::WHITE};
5656

57-
constexpr int_fast8_t MAILBOX[120] = {
57+
constexpr int8_t MAILBOX[120] = {
5858
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
5959
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6060
-1, 0, 1, 2, 3, 4, 5, 6, 7, -1,
@@ -69,7 +69,7 @@ namespace Moves {
6969
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1
7070
};
7171

72-
constexpr int_fast8_t MAILBOX64[64] = {
72+
constexpr int8_t MAILBOX64[64] = {
7373
21, 22, 23, 24, 25, 26, 27, 28,
7474
31, 32, 33, 34, 35, 36, 37, 38,
7575
41, 42, 43, 44, 45, 46, 47, 48,
@@ -81,8 +81,8 @@ namespace Moves {
8181
};
8282

8383
constexpr bool SLIDE[7] = {false, false, false, true, true, true, false};
84-
constexpr int_fast8_t OFFSETS[7] = {0, 4, 8, 4, 4, 8, 8};
85-
constexpr int_fast8_t OFFSET[7][8] = {
84+
constexpr int8_t OFFSETS[7] = {0, 4, 8, 4, 4, 8, 8};
85+
constexpr int8_t OFFSET[7][8] = {
8686
{0, 0, 0, 0, 0, 0, 0, 0},
8787
{8, 9, 11, 16, 0, 0, 0, 0},
8888
{-21, -19, -12, -8, 8, 12, 19, 21},

src/Search.cpp

+13-13
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <thread>
88
#include <format>
99

10-
#define MATE_SCORE 32768 // 1 << 15
10+
#define MATE_SCORE INT32_MAX
1111

1212
TranspositionTable Search::tt = TranspositionTable();
1313

@@ -74,8 +74,8 @@ Move Search::search(ChessBoard&board, const int timeAllowed) {
7474

7575
if (search.lastPV.empty()) {
7676
auto entry = tt.getEntry(board.hashCode, 0);
77-
std::cout << "problem HASH: " << board.hashCode << " TT: key- " << entry.key << ", move- " << entry.bestMove << ", type- " << entry.nodeType() <<
78-
", depth- " << entry.depth() << ", score- " << entry.score() << std::endl;
77+
std::cout << "problem HASH: " << board.hashCode << " TT: key- " << entry.key << ", move- " << entry.bestMove << ", type- " << entry.nodeType <<
78+
", depth- " << entry.depth << ", score- " << entry.score << std::endl;
7979
return NULL_MOVE;
8080
}
8181

@@ -348,14 +348,14 @@ std::vector<Move> Search::collectPV(const int depth) const {
348348
int pvDepth = 0;
349349
while (tt.contains(board.hashCode)) {
350350
const TranspositionTable::Entry entry = tt.getEntry(board.hashCode, 0);
351-
if (entry.nodeType() != TranspositionTable::EXACT) break;
351+
if (entry.nodeType != TranspositionTable::EXACT || entry.depth < 1) break;
352352
Move move = entry.bestMove;
353353

354354
if (pvPositions.contains(board.hashCode)) {
355355
std::cout << "Cycle in PV!" << std::endl;
356356
board.makeMove(move);
357357
pv.push_back(move);
358-
scores.push_back(entry.score());
358+
scores.push_back(entry.score);
359359
pvDepth++;
360360
break;
361361
}
@@ -381,7 +381,7 @@ std::vector<Move> Search::collectPV(const int depth) const {
381381
pvPositions.insert(board.hashCode);
382382
board.makeMove(move);
383383
pv.push_back(move);
384-
scores.push_back(entry.score());
384+
scores.push_back(entry.score);
385385
pvDepth++;
386386
}
387387
std::string pvString;
@@ -404,20 +404,20 @@ std::vector<Move> Search::collectPV(const int depth) const {
404404
bool Search::getTransposition(const uint64_t hash, const int depth, const int ply, int&score, const int&alpha, const int&beta, Move&hashMove) {
405405
if (tt.contains(hash)) {
406406
const TranspositionTable::Entry entry = tt.getEntry(hash, ply);
407-
if (entry.depth() >= depth) {
408-
switch (entry.nodeType()) {
407+
if (entry.depth >= depth) {
408+
switch (entry.nodeType) {
409409
case TranspositionTable::EXACT:
410-
score = entry.score();
410+
score = entry.score;
411411
return true;
412412
case TranspositionTable::UPPERBOUND:
413-
if (entry.score() <= alpha) {
414-
score = entry.score();
413+
if (entry.score <= alpha) {
414+
score = entry.score;
415415
return true;
416416
}
417417
break;
418418
case TranspositionTable::LOWERBOUND:
419-
if (entry.score() >= beta) {
420-
score = entry.score();
419+
if (entry.score >= beta) {
420+
score = entry.score;
421421
return true;
422422
}
423423
default: break;

src/TranspositionTable.cpp

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
#include "TranspositionTable.h"
22
#include <cmath>
3+
#include <cstdio>
34

45
#include "MoveGenerator.h"
56

6-
#define MATE_SCORE 32768 // 1 << 15
7-
#define MIN_MATE_SCORE 16384 // 1 << 14
7+
#define MATE_SCORE INT32_MAX
8+
#define MIN_MATE_SCORE (INT32_MAX - 1024)
89

910
TranspositionTable::Entry TranspositionTable::getEntry(const uint64_t key, const int ply) {
1011
const int index = key % TT_SIZE;
1112
Entry entry = entries[index];
1213

13-
if (abs(entry.score()) >= MIN_MATE_SCORE) {
14-
const int sign = entry.score() > 0 ? 1 : -1;
15-
entry.setScore(sign * (abs(entry.score()) - ply));
14+
if (abs(entry.score) >= MIN_MATE_SCORE) {
15+
const int sign = entry.score > 0 ? 1 : -1;
16+
entry.score = sign * (abs(entry.score) - ply);
1617
}
1718
reads++;
1819

@@ -21,7 +22,7 @@ TranspositionTable::Entry TranspositionTable::getEntry(const uint64_t key, const
2122

2223
bool TranspositionTable::contains(const uint64_t key) {
2324
const int index = key % TT_SIZE;
24-
const bool exists = entries[index].nodeType() != EMPTY;
25+
const bool exists = entries[index].nodeType != EMPTY;
2526
const bool sameKey = (entries[index].key == key);
2627
if (exists && !sameKey) collisions++;
2728

@@ -36,17 +37,17 @@ void TranspositionTable::setEntry(const ChessBoard&board, const Move bestMove, c
3637
score = sign * (abs(score) + ply);
3738
}
3839

39-
const NodeType savedType = entries[index].nodeType();
40+
const NodeType savedType = entries[index].nodeType;
4041

41-
const Entry entry = Entry(board.hashCode, bestMove, depth, score, nodeType);
42+
const Entry entry = {board.hashCode, bestMove, score, static_cast<uint8_t>(depth), nodeType};
4243

4344
//REPLACEMENT SCHEME
4445
// 1. Prefer EXACT nodes to bounds
4546
// 2. Prefer deeper nodes to shallower
4647

4748
if (savedType != EMPTY) {
4849
if ((savedType != EXACT && nodeType != EXACT) || (savedType == EXACT && nodeType == EXACT)) {
49-
if (entries[index].depth() <= depth) write(index, entry);
50+
if (entries[index].depth <= depth) write(index, entry);
5051
}
5152
else if (savedType != EXACT) write(index, entry);
5253
}
@@ -67,16 +68,14 @@ void TranspositionTable::resetCounters() {
6768
int TranspositionTable::occupancy() const {
6869
int occupied = 0;
6970
for (int i = 0; i < TT_SIZE; i++) {
70-
if (entries[i].nodeType() != EMPTY) occupied++;
71+
if (entries[i].nodeType != EMPTY) occupied++;
7172
}
7273
return occupied;
7374
}
7475

7576
void TranspositionTable::clear() {
7677
resetCounters();
7778
for (Entry&entry: entries) {
78-
entry.setNodeType(EMPTY);
79+
entry.nodeType = EMPTY;
7980
}
8081
}
81-
82-
TranspositionTable::TranspositionTable()= default;

src/TranspositionTable.h

+7-39
Original file line numberDiff line numberDiff line change
@@ -18,63 +18,31 @@ class TranspositionTable {
1818
LOWERBOUND = 2,
1919
UPPERBOUND = 3,
2020
};
21-
2221
struct Entry {
23-
uint64_t key;
24-
Move bestMove{};
25-
uint32_t data;
26-
27-
uint8_t depth() const {
28-
return (data & 0xFF0000) >> 16;
29-
}
30-
31-
int16_t score() const {
32-
return data & 0xFFFF;
33-
}
34-
35-
void setScore(int16_t score) {
36-
data = (data & 0xFFF0000) | score;
37-
}
38-
39-
NodeType nodeType() const {
40-
return (NodeType) ((data & 0xF000000) >> 24);
41-
}
42-
43-
void setNodeType(NodeType nodeType) {
44-
data = (data & 0x0FFFFFF) | (((uint8_t) nodeType) << 24);
45-
}
46-
47-
Entry(uint64_t key, Move bestMove, int depth, int score, NodeType nodeType) {
48-
this->key = key;
49-
this->bestMove = bestMove;
50-
this->data = 0 | (0xFFFF & ((int16_t) score)) | (((uint8_t) depth) << 16) | (((uint8_t) nodeType) << 24);
51-
}
52-
53-
Entry() = default;
22+
uint64_t key : 64;
23+
Move bestMove;
24+
int32_t score : 32;
25+
uint8_t depth : 8;
26+
NodeType nodeType : 2;
5427
};
5528

56-
TranspositionTable();
57-
5829
bool contains(uint64_t key);
5930

6031
Entry getEntry(uint64_t key, int ply);
6132

62-
void setEntry(const ChessBoard &board, Move bestMove, int depth, int score, NodeType nodeType, int ply);
33+
void setEntry(const ChessBoard&board, Move bestMove, int depth, int score, NodeType nodeType, int ply);
6334

6435
int reads;
6536
int writes;
6637
int collisions;
67-
6838
void resetCounters();
69-
7039
int occupancy() const;
71-
7240
void clear();
7341

7442
std::array<Entry, TT_SIZE> entries;
7543

7644
private:
77-
void write(int index, const Entry &entry);
45+
void write(int index, const Entry&entry);
7846

7947

8048
};

tests/TranspositionTest.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
#include "TranspositionTable.h"
55
#include "catch2/internal/catch_windows_h_proxy.hpp"
66

7-
#define MATE_SCORE 32768 // 1 << 15
7+
#define MATE_SCORE INT32_MAX
88

99
auto tt = TranspositionTable();
1010

1111
TEST_CASE("TT - rw", "[TranspositionTests]") {
1212
ChessBoard board;
1313
board.setPosition("8/RP1qb1B1/2p2P2/6n1/P7/p3k3/Q3b1BK/6R1 w - - 0 1");
1414
tt.setEntry(board, Interface::CLI::parseMove("f6e7", board), 1, 1, TranspositionTable::EXACT, 1);
15-
auto readEntry = tt.getEntry(board.hashCode, 1);
15+
const auto readEntry = tt.getEntry(board.hashCode, 1);
1616
CHECK(readEntry.bestMove == Interface::CLI::parseMove("f6e7", board));
1717
CHECK(readEntry.depth == 1);
1818
CHECK(readEntry.score == 1);

0 commit comments

Comments
 (0)