diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2026-01-12 18:09:43 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2026-01-12 18:09:43 +0100 |
| commit | 9a013b7c68f94e6be0fe8748c9012a441fe0273f (patch) | |
| tree | d6bb6de992eace566d033d0824c03da89cf7b9cb /doc/h48.md | |
| parent | 83f6533c384a617181e818d1941b08e40aa40b7d (diff) | |
| download | nissy-core-9a013b7c68f94e6be0fe8748c9012a441fe0273f.tar.gz nissy-core-9a013b7c68f94e6be0fe8748c9012a441fe0273f.zip | |
Improve performance of H48 solver with prefetching
With this commit we re-structure how the node expansion in the
H48 solution search works to allow prefetching of pruning values,
showing performance improvements in the range of 30-45% on x86,
depending on table size and solution length.
A small bug fix related to appending solutions is included in this commit.
Diffstat (limited to '')
| -rw-r--r-- | doc/h48.md | 33 |
1 files changed, 25 insertions, 8 deletions
| @@ -251,15 +251,18 @@ Moreover, as an additional heuristic, in case of a 0 read we also look | |||
| 251 | up another pruning value in a table that takes into account only the | 251 | up another pruning value in a table that takes into account only the |
| 252 | position of the edges. This table is small (around 1MB), so repeated | 252 | position of the edges. This table is small (around 1MB), so repeated |
| 253 | accesses to it are not too slow. In practice, this gives a small speed up | 253 | accesses to it are not too slow. In practice, this gives a small speed up |
| 254 | of around 5%. More tables could be used to refine the fallback estimate, | 254 | of around 5% for random scrambles. However, for small solvers (low values |
| 255 | but each additional table leads to longer lookup times, especially if | 255 | of h) and positions where corners are close to solved, this fallback |
| 256 | it is too large to fit in cache. | 256 | table gives dramatic improvements (up to a factor of 1000x in some |
| 257 | manual tests). | ||
| 257 | 258 | ||
| 258 | Previous versions of this implementation (up to commit 6c42463, or | 259 | More tables could be used to refine the fallback estimate, but each |
| 259 | to version 0.2) also included the possibility of a table with 4 bits | 260 | additional table leads to longer lookup times, especially if it is too |
| 260 | per entry, at least for the `h0` case. Such tables did not require | 261 | large to fit in cache. Previous versions of this implementation (up |
| 261 | a fallback lookup, but due to their large size they were not less | 262 | to commit 6c42463, or to version 0.2) also included the possibility of |
| 262 | efficient. Therefore, they have been removed. | 263 | a table with 4 bits per entry, at least for the `h0` case. Such tables |
| 264 | did not require a fallback lookup, but due to their large size they were | ||
| 265 | not less efficient. Therefore, they have been removed. | ||
| 263 | 266 | ||
| 264 | ### Estimation refinements | 267 | ### Estimation refinements |
| 265 | 268 | ||
| @@ -312,6 +315,20 @@ inverse position*, then the coordinate on the normal position has not | |||
| 312 | changed. Thus if we keep track of the last computed pruning value, | 315 | changed. Thus if we keep track of the last computed pruning value, |
| 313 | we can reuse it and avoid an expensive table lookup. | 316 | we can reuse it and avoid an expensive table lookup. |
| 314 | 317 | ||
| 318 | ### Pruning pipeline and prefetching | ||
| 319 | |||
| 320 | To improve the memory access pattern and exploit | ||
| 321 | [prefetching](https://en.wikipedia.org/wiki/Cache_prefetching) | ||
| 322 | opportunities, we don't expand each neighbor one by one in the | ||
| 323 | pruning phase. Instead, we employ a *pruning pipeline*, where we | ||
| 324 | first compute the cube and inverse position for each neighbor, and | ||
| 325 | then we proceed through a series of stages, at each of which we | ||
| 326 | compute some prune off some nodes and we pre-compute the data | ||
| 327 | necessary for the next step. | ||
| 328 | |||
| 329 | This pipeline-based strategy gives an speedup of around 25%. | ||
| 330 | Adding manual prefetching, we get an additional 20% speedup. | ||
| 331 | |||
| 315 | ### Other optimizations | 332 | ### Other optimizations |
| 316 | 333 | ||
| 317 | The H48 solver uses various other optimizations. | 334 | The H48 solver uses various other optimizations. |
