mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 12:47:08 +00:00
On Linux, allow shared-memory network weights to be backed by huge pages
This does require the user to have set `/sys/kernel/mm/transparent_hugepage/shmem_enabled` to something other than `never` (unfortunately the default, at least on Ubuntu).
```
Result of 50 runs
==================
base (...kfish.master) = 1814244 +/- 4396
test (./stockfish ) = 1823756 +/- 3448
diff = +9512 +/- 5496
speedup = +0.0052
P(speedup > 0) = 0.9996
```
```
Performance counter stats for './stockfish bench':
237,561 dTLB-misses
5,783,003,231 cycles
Performance counter stats for './bins/stockfish.master bench':
2,219,832 dTLB-misses
5,932,779,255 cycles
```
closes https://github.com/official-stockfish/Stockfish/pull/6805
No functional change
This commit is contained in:
committed by
Joost VandeVondele
parent
c2500b1165
commit
6a50807e01
+21
-20
@@ -141,23 +141,6 @@ class CleanupHooks {
|
|||||||
inline std::once_flag CleanupHooks::register_once_;
|
inline std::once_flag CleanupHooks::register_once_;
|
||||||
|
|
||||||
|
|
||||||
inline int portable_fallocate(int fd, off_t offset, off_t length) {
|
|
||||||
#ifdef __APPLE__
|
|
||||||
fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, offset, length, 0};
|
|
||||||
int ret = fcntl(fd, F_PREALLOCATE, &store);
|
|
||||||
if (ret == -1)
|
|
||||||
{
|
|
||||||
store.fst_flags = F_ALLOCATEALL;
|
|
||||||
ret = fcntl(fd, F_PREALLOCATE, &store);
|
|
||||||
}
|
|
||||||
if (ret != -1)
|
|
||||||
ret = ftruncate(fd, offset + length);
|
|
||||||
return ret;
|
|
||||||
#else
|
|
||||||
return posix_fallocate(fd, offset, length);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -599,9 +582,6 @@ class SharedMemory: public detail::SharedMemoryBase {
|
|||||||
if (ftruncate(fd_, static_cast<off_t>(total_size_)) == -1)
|
if (ftruncate(fd_, static_cast<off_t>(total_size_)) == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (detail::portable_fallocate(fd_, 0, static_cast<off_t>(total_size_)) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
mapped_ptr_ = mmap(nullptr, total_size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0);
|
mapped_ptr_ = mmap(nullptr, total_size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0);
|
||||||
if (mapped_ptr_ == MAP_FAILED)
|
if (mapped_ptr_ == MAP_FAILED)
|
||||||
{
|
{
|
||||||
@@ -609,6 +589,23 @@ class SharedMemory: public detail::SharedMemoryBase {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MADV_POPULATE_WRITE
|
||||||
|
// Pre-populate, attempting first with THP, to guarantee that the memory
|
||||||
|
// is allocated and avoid crashing on the first write.
|
||||||
|
madvise(mapped_ptr_, total_size_, MADV_HUGEPAGE);
|
||||||
|
|
||||||
|
const bool populated = madvise(mapped_ptr_, total_size_, MADV_POPULATE_WRITE) == 0;
|
||||||
|
#else
|
||||||
|
const bool populated = false;
|
||||||
|
#endif
|
||||||
|
// If the THP population failed, try with fallocate
|
||||||
|
if (!populated && posix_fallocate(fd_, 0, static_cast<off_t>(total_size_)) != 0)
|
||||||
|
{
|
||||||
|
munmap(mapped_ptr_, total_size_);
|
||||||
|
mapped_ptr_ = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
data_ptr_ = static_cast<T*>(mapped_ptr_);
|
data_ptr_ = static_cast<T*>(mapped_ptr_);
|
||||||
header_ptr_ =
|
header_ptr_ =
|
||||||
reinterpret_cast<detail::ShmHeader*>(static_cast<char*>(mapped_ptr_) + sizeof(T));
|
reinterpret_cast<detail::ShmHeader*>(static_cast<char*>(mapped_ptr_) + sizeof(T));
|
||||||
@@ -642,6 +639,10 @@ class SharedMemory: public detail::SharedMemoryBase {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MADV_HUGEPAGE
|
||||||
|
madvise(mapped_ptr_, total_size_, MADV_HUGEPAGE);
|
||||||
|
#endif
|
||||||
|
|
||||||
data_ptr_ = static_cast<T*>(mapped_ptr_);
|
data_ptr_ = static_cast<T*>(mapped_ptr_);
|
||||||
header_ptr_ = std::launder(
|
header_ptr_ = std::launder(
|
||||||
reinterpret_cast<detail::ShmHeader*>(static_cast<char*>(mapped_ptr_) + sizeof(T)));
|
reinterpret_cast<detail::ShmHeader*>(static_cast<char*>(mapped_ptr_) + sizeof(T)));
|
||||||
|
|||||||
Reference in New Issue
Block a user