首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >确保与std::hardware_constructive_interference_size共享的正确方法

确保与std::hardware_constructive_interference_size共享的正确方法
EN

Stack Overflow用户
提问于 2019-02-03 01:29:58
回答 1查看 219关注 0票数 5

什么是正确的和可移植的方式,以确保真正的共享在一个足够小的结构,适合在一个背书?仅仅确保结构足够小就足够了吗?还是也必须在缓存边界上对齐?

例如,假设一条直线的大小为64字节,下面的内容是否足够?

代码语言:javascript
复制
struct A {
  std::uint32_t one;
  std::uint32_t two;
};

还是我必须这么做?

代码语言:javascript
复制
struct alignas(std::hardware_constructive_interference_size) A {
  std::uint32_t one;
  std::uint32_t two;
};

注意:这将始终在堆栈上,因此不需要过度对齐的内存分配。

另一个跟进,这是否足以确保没有虚假分享?

代码语言:javascript
复制
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?)

代码语言:javascript
复制
struct A {
public:
  alignas(hardware_destructive_interference_size) std::uint32_t one;
  alignas(hardware_destructive_interference_size) std::uint32_t two;
};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-03 01:57:41

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

但是,没有100%的可移植方式来对齐缓存行大小。常量hardware_constructive_interference_sizehardware_destructive_interference_size只是提示。它们是编译器的最佳猜测。最终,您不知道编译时的L1缓存行大小。

但在实践中,这通常并不重要,因为对于大多数体系结构来说,有一个典型的缓存行大小,比如x86的64字节。

更重要的是,对于类似于您的示例中的小型结构,只需自然地对齐结构以确保其完全位于缓存行内就足够了。在您的具体示例中,这意味着

代码语言:javascript
复制
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缓存行大小,而只是编译时猜测,这在一定程度上是过度设计的。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54499146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档