Add helpers for managing aligned memory

Previously, we had two type aliases, LargePagePtr and AlignedPtr, which
required manually initializing the aligned memory for the pointer.

The new helpers:

- make_unique_aligned
- make_unique_large_page

are now available for allocating aligned memory (with large pages). They
behave similarly to std::make_unique, ensuring objects allocated with
these functions follow RAII.

The old approach had issues with initializing non-trivial types or
arrays of objects. The evaluation function of the network is now a
unique pointer to an array instead of an array of unique pointers.

Memory related functions have been moved into memory.h

Passed High Hash Pressure Test Non-Regression STC:
https://tests.stockfishchess.org/tests/view/665b2b36586058766677cfd2
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 476992 W: 122426 L: 122677 D: 231889
Ptnml(0-2): 1145, 51027, 134419, 50744, 1161

Failed Normal Non-Regression STC:
https://tests.stockfishchess.org/tests/view/665b2997586058766677cfc8
LLR: -2.94 (-2.94,2.94) <-1.75,0.25>
Total: 877312 W: 225233 L: 226395 D: 425684
Ptnml(0-2): 2110, 94642, 246239, 93630, 2035

Probably a fluke since there shouldn't be a real slowndown and it has also
passed the high hash pressure test.

closes https://github.com/official-stockfish/Stockfish/pull/5332

No functional change
This commit is contained in:
Disservin
2024-05-31 10:53:10 +02:00
parent a2a7edf4c8
commit 00a28ae325
11 changed files with 492 additions and 312 deletions
+2 -46
View File
@@ -26,10 +26,9 @@
#include <cstdint>
#include <cstdio>
#include <iosfwd>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <optional>
#define stringify2(x) #x
#define stringify(x) stringify2(x)
@@ -44,39 +43,10 @@ std::string compiler_info();
// which can be quite slow.
void prefetch(const void* addr);
void start_logger(const std::string& fname);
void* std_aligned_alloc(size_t alignment, size_t size);
void std_aligned_free(void* ptr);
// memory aligned by page size, min alignment: 4096 bytes
void* aligned_large_pages_alloc(size_t size);
// nop if mem == nullptr
void aligned_large_pages_free(void* mem);
void start_logger(const std::string& fname);
size_t str_to_size_t(const std::string& s);
// Deleter for automating release of memory area
template<typename T>
struct AlignedDeleter {
void operator()(T* ptr) const {
ptr->~T();
std_aligned_free(ptr);
}
};
template<typename T>
struct LargePageDeleter {
void operator()(T* ptr) const {
ptr->~T();
aligned_large_pages_free(ptr);
}
};
template<typename T>
using AlignedPtr = std::unique_ptr<T, AlignedDeleter<T>>;
template<typename T>
using LargePagePtr = std::unique_ptr<T, LargePageDeleter<T>>;
#if defined(__linux__)
struct PipeDeleter {
@@ -141,20 +111,6 @@ std::ostream& operator<<(std::ostream&, SyncCout);
#define sync_cout std::cout << IO_LOCK
#define sync_endl std::endl << IO_UNLOCK
// Get the first aligned element of an array.
// ptr must point to an array of size at least `sizeof(T) * N + alignment` bytes,
// where N is the number of elements in the array.
template<uintptr_t Alignment, typename T>
T* align_ptr_up(T* ptr) {
static_assert(alignof(T) < Alignment);
const uintptr_t ptrint = reinterpret_cast<uintptr_t>(reinterpret_cast<char*>(ptr));
return reinterpret_cast<T*>(
reinterpret_cast<char*>((ptrint + (Alignment - 1)) / Alignment * Alignment));
}
// True if and only if the binary is compiled on a little-endian machine
static inline const union {
uint32_t i;