gpt4 book ai didi

c++ - 如何以及何时与缓存行大小对齐?

转载 作者:IT老高 更新时间:2023-10-28 13:23:23 31 4
gpt4 key购买 nike

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

他添加了一些填充变量。我认为这是为了使其与缓存线对齐以提高性能。

我有一些问题。

  1. 为什么会这样?
  2. 它是一种可移植的方法吗?一直在工作
  3. 在什么情况下最好使用 __attribute__
    ((aligned (64)))
    代替。
  4. 为什么缓冲区指针之前的填充有助于提高性能?不只是将指针加载到缓存中,所以它实际上只有指针的大小?

    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 for c 代码下可以工作吗?

最佳答案

这样做是为了让修改不同字段的不同内核不必在它们的缓存之间反弹包含它们的缓存行。一般来说,处理器要访问内存中的某些数据,包含它的整个高速缓存行必须位于该处理器的本地高速缓存中。如果它正在修改该数据,则该缓存条目通常必须是系统中任何缓存中的唯一拷贝(MESI/MOESI 样式缓存一致性协议(protocol)中的独占模式)。当不同的内核尝试修改恰好位于同一缓存行上的不同数据时,从而浪费时间来回移动整行,这被称为错误共享

在您给出的特定示例中,一个核心可以将一个条目入队(读取(共享)buffer_ 并仅写入(独占)enqueue_pos_),而另一个核心出列(共享buffer_ 和独占 dequeue_pos_) 没有任何一个核心停在另一个拥有的缓存行上。

开头的填充意味着 buffer_buffer_mask_ 最终位于同一缓存行上,而不是分成两行,因此需要双倍的内存流量才能访问.

我不确定该技术是否完全可移植。 假设每个 cacheline_pad_t 本身都将与 64 字节(其大小)的缓存行边界对齐,因此接下来的任何内容都将位于下一个缓存行上。据我所知,C 和 C++ 语言标准只要求整个结构都这样,这样它们就可以很好地存在于数组中,而不会违反任何成员的对齐要求。 (见评论)

attribute 方法将更加特定于编译器,但可能会将此结构的大小减半,因为填充将仅限于将每个元素四舍五入为完整的缓存行。如果一个人有很多这些,那可能会非常有益。

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

关于c++ - 如何以及何时与缓存行大小对齐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8469427/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com