Use static alignment for DataLayout
This commit is contained in:
		
							parent
							
								
									f7b7335d75
								
							
						
					
					
						commit
						653f647fee
					
				| @ -16,14 +16,12 @@ struct Block | |||||||
| { | { | ||||||
|     std::uint64_t num_entries; |     std::uint64_t num_entries; | ||||||
|     std::uint64_t byte_size; |     std::uint64_t byte_size; | ||||||
|     std::uint64_t entry_size; |  | ||||||
|     std::uint64_t entry_align; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template <typename T> Block make_block(uint64_t num_entries) | template <typename T> Block make_block(uint64_t num_entries) | ||||||
| { | { | ||||||
|     static_assert(sizeof(T) % alignof(T) == 0, "aligned T* can't be used as an array pointer"); |     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}; | ||||||
| } | } | ||||||
| } | } | ||||||
| } | } | ||||||
|  | |||||||
| @ -94,8 +94,9 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA", | |||||||
|                                             "MANEUVER_OVERRIDES", |                                             "MANEUVER_OVERRIDES", | ||||||
|                                             "MANEUVER_OVERRIDE_NODE_SEQUENCES"}; |                                             "MANEUVER_OVERRIDE_NODE_SEQUENCES"}; | ||||||
| 
 | 
 | ||||||
| struct DataLayout | class DataLayout | ||||||
| { | { | ||||||
|  |   public: | ||||||
|     enum BlockID |     enum BlockID | ||||||
|     { |     { | ||||||
|         NAME_CHAR_DATA = 0, |         NAME_CHAR_DATA = 0, | ||||||
| @ -174,8 +175,6 @@ struct DataLayout | |||||||
|         NUM_BLOCKS |         NUM_BLOCKS | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     std::array<Block, NUM_BLOCKS> blocks; |  | ||||||
| 
 |  | ||||||
|     DataLayout() : blocks{} {} |     DataLayout() : blocks{} {} | ||||||
| 
 | 
 | ||||||
|     inline void SetBlock(BlockID bid, Block block) { blocks[bid] = std::move(block); } |     inline void SetBlock(BlockID bid, Block block) { blocks[bid] = std::move(block); } | ||||||
| @ -189,47 +188,17 @@ struct DataLayout | |||||||
|         uint64_t result = 0; |         uint64_t result = 0; | ||||||
|         for (auto i = 0; i < NUM_BLOCKS; i++) |         for (auto i = 0; i < NUM_BLOCKS; i++) | ||||||
|         { |         { | ||||||
|             BOOST_ASSERT(blocks[i].entry_align > 0); |             result += 2 * sizeof(CANARY) + GetBlockSize(static_cast<BlockID>(i)) + BLOCK_ALIGNMENT; | ||||||
|             result += 2 * sizeof(CANARY) + GetBlockSize((BlockID)i) + blocks[i].entry_align; |  | ||||||
|         } |         } | ||||||
|         return result; |         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<uintptr_t>(ptr); |  | ||||||
|         const auto aligned = (intptr - 1u + align) & -align; |  | ||||||
|         return ptr = reinterpret_cast<void *>(aligned); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     inline void *GetAlignedBlockPtr(void *ptr, BlockID bid) const |  | ||||||
|     { |  | ||||||
|         for (auto i = 0; i < bid; i++) |  | ||||||
|         { |  | ||||||
|             ptr = static_cast<char *>(ptr) + sizeof(CANARY); |  | ||||||
|             ptr = align(blocks[i].entry_align, blocks[i].entry_size, ptr); |  | ||||||
|             ptr = static_cast<char *>(ptr) + GetBlockSize((BlockID)i); |  | ||||||
|             ptr = static_cast<char *>(ptr) + sizeof(CANARY); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         ptr = static_cast<char *>(ptr) + sizeof(CANARY); |  | ||||||
|         ptr = align(blocks[bid].entry_align, blocks[bid].entry_size, ptr); |  | ||||||
|         return ptr; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     template <typename T> inline T *GetBlockEnd(char *shared_memory, BlockID bid) const |  | ||||||
|     { |  | ||||||
|         auto begin = GetBlockPtr<T>(shared_memory, bid); |  | ||||||
|         return begin + GetBlockEntries(bid); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     template <typename T, bool WRITE_CANARY = false> |     template <typename T, bool WRITE_CANARY = false> | ||||||
|     inline T *GetBlockPtr(char *shared_memory, BlockID bid) const |     inline T *GetBlockPtr(char *shared_memory, BlockID bid) const | ||||||
|     { |     { | ||||||
|  |         static_assert(BLOCK_ALIGNMENT % std::alignment_of<T>::value == 0, | ||||||
|  |                       "Datatype does not fit alignment constraints."); | ||||||
|  | 
 | ||||||
|         char *ptr = (char *)GetAlignedBlockPtr(shared_memory, bid); |         char *ptr = (char *)GetAlignedBlockPtr(shared_memory, bid); | ||||||
|         if (WRITE_CANARY) |         if (WRITE_CANARY) | ||||||
|         { |         { | ||||||
| @ -258,6 +227,39 @@ struct DataLayout | |||||||
| 
 | 
 | ||||||
|         return (T *)ptr; |         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<uintptr_t>(ptr); | ||||||
|  |         const auto aligned = (intptr - 1u + BLOCK_ALIGNMENT) & -BLOCK_ALIGNMENT; | ||||||
|  |         return ptr = reinterpret_cast<void *>(aligned); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline void *GetAlignedBlockPtr(void *ptr, BlockID bid) const | ||||||
|  |     { | ||||||
|  |         for (auto i = 0; i < bid; i++) | ||||||
|  |         { | ||||||
|  |             ptr = static_cast<char *>(ptr) + sizeof(CANARY); | ||||||
|  |             ptr = align(ptr); | ||||||
|  |             ptr = static_cast<char *>(ptr) + GetBlockSize((BlockID)i); | ||||||
|  |             ptr = static_cast<char *>(ptr) + sizeof(CANARY); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         ptr = static_cast<char *>(ptr) + sizeof(CANARY); | ||||||
|  |         ptr = align(ptr); | ||||||
|  |         return ptr; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     template <typename T> inline T *GetBlockEnd(char *shared_memory, BlockID bid) const | ||||||
|  |     { | ||||||
|  |         auto begin = GetBlockPtr<T>(shared_memory, bid); | ||||||
|  |         return begin + GetBlockEntries(bid); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static constexpr std::size_t BLOCK_ALIGNMENT = 64; | ||||||
|  |     std::array<Block, NUM_BLOCKS> blocks; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| enum SharedDataType | enum SharedDataType | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user