【问题标题】:What are the most common configurations where pointer writes are not atomic?指针写入不是原子的最常见配置是什么?
【发布时间】:2011-01-20 10:47:22
【问题描述】:

我对多线程感兴趣。该领域有很多陷阱,例如,不能保证指针写入是原子的。我明白了,但想知道实际情况下最流行的当前配置是什么?例如,在我的 Macbook Pro/gcc 上,指针写入肯定是原子的。

【问题讨论】:

  • 如果指针存储在未对齐的内存位置(这样它的值可能存储在两个不同的缓存行中?
  • @jdv:这不太可能是偶然发生的。所以我对这种情况不感兴趣。
  • 即使它们是原子的,您也会遇到可见性问题 - 除非得到照顾,否则该指针可能存储在寄存器中而从未写入内存 - 或者内存写入可能是重新排序,当你认为它根据你的代码发生时不会发生

标签: c++ c multithreading atomic


【解决方案1】:

这主要是指针宽度大于 CPU 架构宽度的 CPU 架构的问题。例如,在ATmega CPU(一个 8 位架构)上,地址空间是 16 位。如果没有任何特定指令来加载和存储 16 位地址,则至少需要两条指令来加载/存储指针值。

【讨论】:

  • 是的,我知道 - 现在对桌面/服务器架构更感兴趣,但这是一个很好的答案。
【解决方案2】:

here

【讨论】:

  • 这会更好作为对问题的评论(也许是作为重复关闭的建议)
【解决方案3】:

正如 Daniel 所说,几乎每个架构都会受到影响。除非强制执行内存对齐,否则每次写入都可能导致多个操作,但如果地址总线小于数据总线,这也会失败。因此,您很可能需要使用锁定机制编写代码。这无论如何都是一个好主意,因为您可能希望您的代码是可移植的。对于一些非常特殊的架构,这些锁定函数只是空的。

【讨论】:

  • 你知道除 ATmega 之外的其他平台吗?
  • 根据我的经验,在这种情况下,“非常特殊的架构”会转化为“大多数架构”。
【解决方案4】:

在使用分段地址空间的平台(如 MS-DOS 或 Win 3.x)上,指针可能不是原子类型。但我不知道有任何现代桌面/服务器平台使用这种架构(至少在平台级别)。

但是,即使从 C 编译器的角度来看,写入是原子性的,也可能存在其他问题,即使在现代桌面/服务器系统上,尤其是在处理多核/多处理器系统时(缓存、内存处理器在较低级别完成的访问重新排序)。平台提供的“原子”API 使用内存屏障(如果需要)来处理这些问题,因此在尝试确保内存访问是原子的时,您仍然应该使用这些 API。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    相关资源
    最近更新 更多