正确的方法,以确保与标准:: hardware_constructive_interference_size共享

问题描述 投票:4回答:1

什么是确保在结构足够小,适合在高速缓存行真正共享的正确和可移植的方法?它是不够的,只是确保结构足够小?或者它也有高速缓存边界上对齐?

例如,假定一个高速缓存行的大小为64个字节,是以下足够?

struct A {
  std::uint32_t one;
  std::uint32_t two;
};

还是我必须这样做?

struct alignas(std::hardware_constructive_interference_size) A {
  std::uint32_t one;
  std::uint32_t two;
};

注意:这将永远是在栈上,所以没有过度对齐的存储空间的分配应符合规定。


另一个随访,这是足以保证共享假没有?

struct A {
public:
  alignas(hardware_destructive_interference_size) std::uint32_t one;
  alignas(hardware_constructive_interference_size) std::uint32_t two;
};

或者没有一个不得不这样做(在说hardware_constructive_interference_size <hardware_destructive_interference_size的情况?)

struct A {
public:
  alignas(hardware_destructive_interference_size) std::uint32_t one;
  alignas(hardware_destructive_interference_size) std::uint32_t two;
};
c++ alignment c++17
1个回答
4
投票

目前第二个变量是你能做的最好的。

然而,没有对齐到高速缓存行大小的100%可移植的方式。常量hardware_constructive_interference_sizehardware_destructive_interference_size只是暗示。他们是编译器的最佳猜测。最终,你不知道在编译时的L1高速缓存行的大小。

但在实践中,这通常并不重要,因为对于大多数的架构有一个典型的高速缓存行的大小,如64个字节用于x86。

更有甚者,在你的例子小结构一样,它始终是足够的自然对齐结构,以确保它完全是一个高速缓存行内。在您的具体的例子,这意味着

struct alignas(8) A {
  std::uint32_t one;
  std::uint32_t two;
};

将始终确保真正共享,而不管在运行时实际L1高速缓存行大小的,条件是该高速缓存行大小为8个字节或更大。 (如果是较小的,你将永远不会有真正的共享平凡。)

关于后续问题:第二个变量将确保共享假没有。第一个变种可能导致错误共享的高速缓存行大小可能真的hardware_destructive_interference_size在这种情况下,你将有共享假的(在假设hardware_constructive_interference_size <hardware_destructive_interference_size)。

但在实践中hardware_destructive_interference_sizehardware_constructive_interference_size会对大多数架构相同的值。这有点过度设计,因为没有恒定为您提供真正的L1高速缓存行的大小,但只是一个编译时的猜测。

© www.soinside.com 2019 - 2024. All rights reserved.