|
Orrery
A GPU-accelerated N-body gravitational simulator
|
An allocator that starts every allocation on a cache line. More...
#include <cstddef>#include <limits>#include <new>#include <type_traits>Go to the source code of this file.
Classes | |
| class | orrery::core::AlignedAllocator< T > |
| A standard allocator that returns cache-line-aligned storage. More... | |
Functions | |
| template<typename T, typename U> | |
| constexpr bool | orrery::core::operator== (const AlignedAllocator< T > &, const AlignedAllocator< U > &) noexcept |
| All instances are interchangeable, whatever their value type, because the allocator holds nothing that could distinguish them. | |
Variables | |
| constexpr std::size_t | orrery::core::kCacheLineBytes = 64 |
| The cache line length on the target machine, in bytes. | |
An allocator that starts every allocation on a cache line.
The target machine shares roughly 135 GB/s of memory bandwidth between its CPU and its integrated GPU, and most kernels in this project are bound by data movement rather than arithmetic. Two consequences follow from where an array begins, and both are paid for by the kernel rather than by the allocation.
A 256-bit AVX2 load reads 32 bytes. From an array whose first element sits at an arbitrary offset, some of those loads straddle two 64-byte cache lines, and a split load costs two line fills instead of one. Starting the array on a line means an aligned load stays inside a line for the whole array.
The threading in Phase 6 divides each component array into per-thread ranges. Where two ranges share a cache line, the two threads writing them contend for exclusive ownership of that line even though neither touches the other's elements. Aligning the array is the first half of avoiding that; the second half is choosing partition boundaries on line multiples, which is the scheduler's job rather than the allocator's.
ADR-0005 records the alternatives.
|
inlineconstexpr |
The cache line length on the target machine, in bytes.
64 on the Lion Cove and Skymont cores of Lunar Lake, as on every other x86-64 part this project runs on. It is a constant rather than a query because it has to be usable in a constant expression, and because a value discovered at run time could not be relied on by anything compiled against it.