Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Functional simplification in the transposition table #5263

Closed
wants to merge 1 commit into from

Conversation

FauziAkram
Copy link
Contributor

Functional simplification in the transposition table.

Passed STC:
LLR: 2.98 (-2.94,2.94) <-1.75,0.25>
Total: 154848 W: 39838 L: 39750 D: 75260
Ptnml(0-2): 404, 16214, 44087, 16328, 391
https://tests.stockfishchess.org/tests/view/664892b088b8c6a2bbe430fc

Passed LTC:
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 68172 W: 17296 L: 17137 D: 33739
Ptnml(0-2): 23, 6349, 21185, 6504, 25
https://tests.stockfishchess.org/tests/view/6648aabfa0781149e383e526

bench: 1426724

bench: 1426724
@@ -123,7 +123,7 @@ TTEntry* TranspositionTable::probe(const Key key, bool& found) const {
const uint16_t key16 = uint16_t(key); // Use the low 16 bits as key inside the cluster

for (int i = 0; i < ClusterSize; ++i)
if (tte[i].key16 == key16 || !tte[i].depth8)
if (tte[i].key16 == key16)
return found = bool(tte[i].depth8), &tte[i];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you example now what the bool(tte[i].depth8) does, what's the typical value?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you example now what the bool(tte[i].depth8) does, what's the typical value?

bool(tte[i].depth8) checks for if the entry is found or not
the trick of the depth offsetting with -7 , is it makes depth 0 truthy from qsearch because int(0) is false..
Now since we use a pointer to the entry we can return the entry but not consider it as found, so I assume the older code, was trying to make the code smarter by forcing where to save the entry.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patch makes no sense, imho. As soon as we find an empty slot, we want to return immediately.

Copy link
Contributor

@peregrineshahin peregrineshahin May 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but my question is, doesn't the patch already make an entire cluster non-functioning?
to me it seems like the first cluster is never used for saving here. because the loop to follow bellow starts from 1?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works because the first cluser is set as default replacement in line 130. The loop checks only if one of the other clusters in better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i.e. the entries to return from for a no-found entry, is always coming from replacement strategy below which is never from tte[0], this sounds fine, but at the same time, how can the first cluster ever have entries saved onto it, if we never say the first entry has empty slots and the first cluster never having any keys?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry indeed that works...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes so what this patch does is it replaces always based on relative age and never on the bases that an entry is empty..
fascinating to me that it passed

@peregrineshahin
Copy link
Contributor

I think this is very sensitive topic, logically I can't pass beyond how replacing old entries should be any better than filling out empty entries. I have concerns if this can scale with lots of memory available while we overwrite old entries for no reason.

@mstembera
Copy link
Contributor

I think the reason this passes is because there are few if any empty entries left after just one or two moves of a game. Also the empty entries will start with generation 0 which will be older than any stored entries. IF we consider committing this I would suggest at least running some high hash pressure tests. Say 2MB STC or 8MB LTC.

@FauziAkram
Copy link
Contributor Author

I think the reason this passes is because there are few if any empty entries left after just one or two moves of a game. Also the empty entries will start with generation 0 which will be older than any stored entries. IF we consider committing this I would suggest at least running some high hash pressure tests. Say 2MB STC or 8MB LTC.

Can pls someone run them on my behalf?

@mstembera
Copy link
Contributor

I'm happy to do it. Let's see what if anything the maintainers want first.

@vondele
Copy link
Member

vondele commented May 18, 2024

I'm a bit skeptical about this patch, but would like to have the data of the patch at high hash pressure indeed.

@mstembera
Copy link
Contributor

mstembera commented May 18, 2024

https://tests.stockfishchess.org/tests/view/66491b2fb8fa20e74c39f41d
[Edit] Passed high pressure
LLR: 2.95 (-2.94,2.94) <-1.75,0.25>
Total: 249504 W: 64138 L: 64151 D: 121215
Ptnml(0-2): 765, 26744, 69694, 26837, 712

@peregrineshahin
Copy link
Contributor

I would have thought that the test needed is less pressure rather than high pressure i.e. trying to show that filling empty entries is better than replacing old ones.
I think we should consider the effect of this on SF analysis which IMO would be disastrous, if hash is cleared, then there is no entries to replace because the memory will not be full when large memory settings is used leaving us with replacing what we consistantly write.

@mstembera
Copy link
Contributor

mstembera commented May 19, 2024

You are probably right and this affects the low pressure scenario more than the high. The replacement policy should still select the empty entries first for replacement since they will be the oldest with the lowest depths. It's just that instead of returning an empty entry immediately we spend time executing the replacement policy code. On the other hand when the TT fills up and there are no empty entries left the !tte[i].depth8 check becomes wasteful and useless.
https://tests.stockfishchess.org/tests/view/6649555cb8fa20e74c39f43d
[Edit] Passed low pressure
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 103392 W: 26645 L: 26504 D: 50243
Ptnml(0-2): 334, 11219, 28438, 11382, 323

@vondele vondele added the simplification A simplification patch label May 21, 2024
@Disservin Disservin added the to be merged Will be merged shortly label May 30, 2024
@Disservin Disservin closed this in d1a71fd May 30, 2024
dubslow added a commit to dubslow/Stockfish that referenced this pull request Jun 14, 2024
(and fix a stray comment)

I say "fix" due official-stockfish#5263 and its lengthy discussion. Beyond that, this is a clear readability and maintainbility improvement for beginners and experts alike.

Passed STC non-reg: https://tests.stockfishchess.org/tests/view/66695b6a602682471b064cfc
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 107520 W: 28138 L: 27998 D: 51384
Ptnml(0-2): 373, 12257, 28358, 12401, 371

no functional change
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
simplification A simplification patch to be merged Will be merged shortly
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants