https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105251
--- Comment #9 from Khem Raj <raj.khem at gmail dot com> --- how does something like this look ? #include <cstdint> #include <cstddef> #include <new> #include <algorithm> #ifdef __cpp_lib_hardware_interference_size using std::hardware_constructive_interference_size; using std::hardware_destructive_interference_size; #else // 64 bytes on x86-64 │ L1_CACHE_BYTES │ L1_CACHE_SHIFT │ __cacheline_aligned │ ... constexpr std::size_t hardware_constructive_interference_size = 64; constexpr std::size_t hardware_destructive_interference_size = 64; #endif class NetworkCounter { private: template <typename T, size_t alignment> struct alignas(alignment) WithAlignment : T { using T::T; }; template <typename T, size_t alignment> using WithAlignmentAtLeast = WithAlignment<T, std::max(alignof(T), alignment)>; // These two counters are always incremented at the same time, so // we place them on the same cache line. template <typename T> using CacheAligned = WithAlignmentAtLeast<T, hardware_constructive_interference_size>; struct Together { long long logicalBytesIn{0}; long long requests{0}; }; CacheAligned<Together> _together{}; static_assert(sizeof(decltype(_together)) <= hardware_destructive_interference_size, "cache line spill"); };