cache_aligned.h (2112B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #ifndef LIB_JXL_BASE_CACHE_ALIGNED_H_ 7 #define LIB_JXL_BASE_CACHE_ALIGNED_H_ 8 9 // Memory allocator with support for alignment + misalignment. 10 11 #include <stddef.h> 12 #include <stdint.h> 13 14 #include <memory> 15 16 #include "lib/jxl/base/compiler_specific.h" 17 18 namespace jxl { 19 20 // Functions that depend on the cache line size. 21 class CacheAligned { 22 public: 23 static void PrintStats(); 24 25 static constexpr size_t kPointerSize = sizeof(void*); 26 static constexpr size_t kCacheLineSize = 64; 27 // To avoid RFOs, match L2 fill size (pairs of lines). 28 static constexpr size_t kAlignment = 2 * kCacheLineSize; 29 // Minimum multiple for which cache set conflicts and/or loads blocked by 30 // preceding stores can occur. 31 static constexpr size_t kAlias = 2048; 32 33 // Returns a 'random' (cyclical) offset suitable for Allocate. 34 static size_t NextOffset(); 35 36 // Returns null or memory whose address is congruent to `offset` (mod kAlias). 37 // This reduces cache conflicts and load/store stalls, especially with large 38 // allocations that would otherwise have similar alignments. At least 39 // `payload_size` (which can be zero) bytes will be accessible. 40 static void* Allocate(size_t payload_size, size_t offset); 41 42 static void* Allocate(const size_t payload_size) { 43 return Allocate(payload_size, NextOffset()); 44 } 45 46 static void Free(const void* aligned_pointer); 47 }; 48 49 // Avoids the need for a function pointer (deleter) in CacheAlignedUniquePtr. 50 struct CacheAlignedDeleter { 51 void operator()(uint8_t* aligned_pointer) const { 52 CacheAligned::Free(aligned_pointer); 53 } 54 }; 55 56 using CacheAlignedUniquePtr = std::unique_ptr<uint8_t[], CacheAlignedDeleter>; 57 58 // Does not invoke constructors. 59 static inline CacheAlignedUniquePtr AllocateArray(const size_t bytes) { 60 return CacheAlignedUniquePtr( 61 static_cast<uint8_t*>(CacheAligned::Allocate(bytes)), 62 CacheAlignedDeleter()); 63 } 64 65 } // namespace jxl 66 67 #endif // LIB_JXL_BASE_CACHE_ALIGNED_H_