diff --git a/include/storage/block.hpp b/include/storage/block.hpp index cf3d6a16b..2b895c44f 100644 --- a/include/storage/block.hpp +++ b/include/storage/block.hpp @@ -16,14 +16,12 @@ struct Block { std::uint64_t num_entries; std::uint64_t byte_size; - std::uint64_t entry_size; - std::uint64_t entry_align; }; template Block make_block(uint64_t num_entries) { static_assert(sizeof(T) % alignof(T) == 0, "aligned T* can't be used as an array pointer"); - return Block{num_entries, sizeof(T) * num_entries, sizeof(T), alignof(T)}; + return Block{num_entries, sizeof(T) * num_entries}; } } } diff --git a/include/storage/shared_datatype.hpp b/include/storage/shared_datatype.hpp index 4c2c973b4..573708288 100644 --- a/include/storage/shared_datatype.hpp +++ b/include/storage/shared_datatype.hpp @@ -94,8 +94,9 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA", "MANEUVER_OVERRIDES", "MANEUVER_OVERRIDE_NODE_SEQUENCES"}; -struct DataLayout +class DataLayout { + public: enum BlockID { NAME_CHAR_DATA = 0, @@ -174,8 +175,6 @@ struct DataLayout NUM_BLOCKS }; - std::array blocks; - DataLayout() : blocks{} {} inline void SetBlock(BlockID bid, Block block) { blocks[bid] = std::move(block); } @@ -189,47 +188,17 @@ struct DataLayout uint64_t result = 0; for (auto i = 0; i < NUM_BLOCKS; i++) { - BOOST_ASSERT(blocks[i].entry_align > 0); - result += 2 * sizeof(CANARY) + GetBlockSize((BlockID)i) + blocks[i].entry_align; + result += 2 * sizeof(CANARY) + GetBlockSize(static_cast(i)) + BLOCK_ALIGNMENT; } return result; } - // \brief Fit aligned storage in buffer. - // Interface Similar to [ptr.align] but omits space computation. - // The method can be removed and changed directly to an std::align - // function call after dropping gcc < 5 support. - inline void *align(std::size_t align, std::size_t, void *&ptr) const noexcept - { - const auto intptr = reinterpret_cast(ptr); - const auto aligned = (intptr - 1u + align) & -align; - return ptr = reinterpret_cast(aligned); - } - - inline void *GetAlignedBlockPtr(void *ptr, BlockID bid) const - { - for (auto i = 0; i < bid; i++) - { - ptr = static_cast(ptr) + sizeof(CANARY); - ptr = align(blocks[i].entry_align, blocks[i].entry_size, ptr); - ptr = static_cast(ptr) + GetBlockSize((BlockID)i); - ptr = static_cast(ptr) + sizeof(CANARY); - } - - ptr = static_cast(ptr) + sizeof(CANARY); - ptr = align(blocks[bid].entry_align, blocks[bid].entry_size, ptr); - return ptr; - } - - template inline T *GetBlockEnd(char *shared_memory, BlockID bid) const - { - auto begin = GetBlockPtr(shared_memory, bid); - return begin + GetBlockEntries(bid); - } - template inline T *GetBlockPtr(char *shared_memory, BlockID bid) const { + static_assert(BLOCK_ALIGNMENT % std::alignment_of::value == 0, + "Datatype does not fit alignment constraints."); + char *ptr = (char *)GetAlignedBlockPtr(shared_memory, bid); if (WRITE_CANARY) { @@ -258,6 +227,39 @@ struct DataLayout return (T *)ptr; } + + private: + // Fit aligned storage in buffer to 64 bytes to conform with AVX 512 types + inline void *align(void *&ptr) const noexcept + { + const auto intptr = reinterpret_cast(ptr); + const auto aligned = (intptr - 1u + BLOCK_ALIGNMENT) & -BLOCK_ALIGNMENT; + return ptr = reinterpret_cast(aligned); + } + + inline void *GetAlignedBlockPtr(void *ptr, BlockID bid) const + { + for (auto i = 0; i < bid; i++) + { + ptr = static_cast(ptr) + sizeof(CANARY); + ptr = align(ptr); + ptr = static_cast(ptr) + GetBlockSize((BlockID)i); + ptr = static_cast(ptr) + sizeof(CANARY); + } + + ptr = static_cast(ptr) + sizeof(CANARY); + ptr = align(ptr); + return ptr; + } + + template inline T *GetBlockEnd(char *shared_memory, BlockID bid) const + { + auto begin = GetBlockPtr(shared_memory, bid); + return begin + GetBlockEntries(bid); + } + + static constexpr std::size_t BLOCK_ALIGNMENT = 64; + std::array blocks; }; enum SharedDataType