std::hardware_destructive_interference_size, std::hardware_constructive_interference_size

< cpp‎ | thread
在标头 <new> 定义
inline constexpr std::size_t
    hardware_destructive_interference_size = /* 由实现定义 */;
(1) (C++17 起)
inline constexpr std::size_t
    hardware_constructive_interference_size = /* 由实现定义 */;
(2) (C++17 起)
1) 两个对象间避免假数据共享的最小偏移。保证至少为 alignof(std::max_align_t)
struct keep_apart
{
    alignas(std::hardware_destructive_interference_size) std::atomic<int> cat;
    alignas(std::hardware_destructive_interference_size) std::atomic<int> dog;
};
2) 鼓励真共享的最大连续内存大小。保证至少为 alignof(std::max_align_t)
struct together
{
    std::atomic<int> dog;
    int puppy;
};
 
struct kennel
{
    // 其他数据成员……
 
    alignas(sizeof(together)) together pack;
 
    // 其他数据成员……
};
 
static_assert(sizeof(together) <= std::hardware_constructive_interference_size);

注解

这些常量提供一种可移植的访问 L1 数据缓存行大小的方式。

功能特性测试 标准 功能特性
__cpp_lib_hardware_interference_size 201703L (C++17) constexpr std::hardware_constructive_interference_size

constexpr std::hardware_destructive_interference_size

示例

程序使用两个线程(原子地)写入给定全局对象的数据成员。第一个对象适合于存入一条缓存行内,这导致“硬件干涉”。第二个对象保持其数据成员在分离的缓存行上,故避免了线程写入后可能的“缓存同步”。

#include <iostream>
#include <thread>
#include <chrono>
 
#ifdef __cpp_lib_hardware_interference_size
using std::hardware_constructive_interference_size;
using std::hardware_destructive_interference_size;
#else
// 在 x86-64 │ L1_CACHE_BYTES │ L1_CACHE_SHIFT │ __cacheline_aligned │ ... 上为 64 字节
constexpr std::size_t hardware_constructive_interference_size = 64;
constexpr std::size_t hardware_destructive_interference_size = 64;
#endif
 
struct one_cache_liner
{
        ::std::atomic_uint64_t x{};
        ::std::atomic_uint64_t y{};
};
 
struct two_cache_liner
{
        alignas(hardware_destructive_interference_size)::std::atomic_uint64_t x{};
        alignas(hardware_destructive_interference_size)::std::atomic_uint64_t y{};
};
 
inline auto increment_thread(::std::atomic_uint64_t &u)
{
        return [&] {
                constexpr int max_write_iterations{10'000'000};
                for (::std::size_t i{}; i < max_write_iterations; ++i)
                {
                        u.fetch_add(1, ::std::memory_order_relaxed);
                };
        };
}
 
template <typename T>
auto parallel_increment(T &&t)
{
        ::std::jthread th1{increment_thread(t.x)};
        ::std::jthread th2{increment_thread(t.y)};
}
 
struct timer
{
        timer()
                : beg(::std::chrono::high_resolution_clock::now())
        {}
        ~timer()
        {
                ::std::cout << ::std::chrono::high_resolution_clock::now() - beg << '\n';
        }
        ::std::chrono::high_resolution_clock::time_point beg;
};
 
int main()
{
        ::std::cout << "hardware_constructive_interference_size = " 
                        << hardware_constructive_interference_size << '\n';
        ::std::cout << "hardware_destructive_interference_size = "
                        << hardware_destructive_interference_size << '\n';
 
        ::std::chrono::high_resolution_clock::now();
        {
                ::std::cout << "sizeof(one_cache_liner) = " << sizeof(one_cache_liner) << '\n';
                timer t;
                parallel_increment(one_cache_liner{});
        }
        {
                ::std::cout << "sizeof(two_cache_liner) = " << sizeof(two_cache_liner) << '\n';
                timer t;
                parallel_increment(two_cache_liner{});
        }
}

可能的输出:

hardware_constructive_interference_size = 64
hardware_destructive_interference_size = 64
sizeof(one_cache_liner) = 16
182019200ns
sizeof(two_cache_liner) = 128
35766400ns

参阅

返回实现支持的并发线程数
(std::thread 的公开静态成员函数)
返回实现支持的并发线程数
(std::jthread 的公开静态成员函数)