如何以及何时alignment高速caching行大小?

在Dmitry Vyukov用C ++编写的优秀有界mpmc队列见: http ://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmcqueue

他添加了一些填充variables。 我认为这是为了使其与高速caching行alignment以达到性能。

我有一些疑问。

  1. 为什么这样做呢?
  2. 这是一个便携式的方法,将始终工作
  3. 在什么情况下最好使用__attribute__ ((aligned (64)))来代替。
  4. 为什么在缓冲区指针帮助性能之前填充? 是不是只是加载到caching的指针,所以它只是一个指针的大小?

     static size_t const cacheline_size = 64; typedef char cacheline_pad_t [cacheline_size]; cacheline_pad_t pad0_; cell_t* const buffer_; size_t const buffer_mask_; cacheline_pad_t pad1_; std::atomic<size_t> enqueue_pos_; cacheline_pad_t pad2_; std::atomic<size_t> dequeue_pos_; cacheline_pad_t pad3_; 

这个概念是否在gcc的c代码下工作?

这样做是为了让修改不同字段的不同内核不必在高速caching之间反弹包含它们的高速caching行。 通常,对于处理器访问内存中的某些数据,包含它的整个caching行必须位于该处理器的本地caching中。 如果正在修改该数据,则该caching条目通常必须是系统中任何caching中唯一的副本(MESI / MOESI样式caching一致性协议中的独占模式)。 当单独的内核尝试修改发生在同一个caching行上的不同数据,从而浪费时间来回移动整个行时,这就是所谓的虚假共享

在你给出的特定例子中,一个核心可以排队一个入口(读取(共享) buffer_和写入(排除) enqueue_pos_ ),而另一个核心dequeue_pos_ (共享buffer_和独占dequeue_pos_ ) 。

填充开头意味着buffer_buffer_mask_结束在同一个caching行上,而不是分成两行,因此需要双倍的内存访问量来访问。

我不确定这种技术是否完全可移植。 假定每个cacheline_pad_t本身将被alignment到一个64字节(它的大小)的caching线边界,因此它将在下一个caching线之后。 据我所知,C和C ++语言标准只需要整个结构的这种标准,这样他们就可以很好地生活在数组中,而不违反任何成员的alignment要求。 (看评论)

attribute方法会更具体的编译器,但可能会减less一半的结构的大小,因为填充将被限制为将每个元素四舍五入到一个完整的caching行。 如果有很多这些,这可能是相当有益的。

C和C ++一样适用于同样的概念。