std::hardware_destructive_interference_size, std::hardware_constructive_interference_size
来自cppreference.com
<tbody>
</tbody>
| 在标头 <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 和
|
示例
程序使用两个线程(原子地)写入给定全局对象的数据成员。第一个对象适合于存入一条缓存行内,这导致“硬件干涉”。第二个对象保持其数据成员在分离的缓存行上,故避免了线程写入后可能的“缓存同步”。
运行此代码
#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 的公开静态成员函数)
|