美文网首页
[译]如果对齐内存的写入是原子性的,为什么我们还需要sync/a

[译]如果对齐内存的写入是原子性的,为什么我们还需要sync/a

作者: 豆腐匠 | 来源:发表于2021-01-13 18:02 被阅读0次

原文地址:https://dave.cheney.net/2018/01/06/if-aligned-memory-writes-are-atomic-why-do-we-need-the-sync-atomic-package

这是受到在Go论坛上一篇帖子的启发想到的问题。问题的大意是:“如果处理器保证正确对齐的写入是原子的,那么为什么还需要数据竞态检测器?”

答案是,原子这个词在这里有两种用法。第一个是OP引用的,是大多数微处理器的属性,只要写入的地址自然对齐即可,例如,如果它是32位,则始终将其写入到一个地址中,占位四的倍数-那么没有东西会注意到占位一半的值。

为了解释这意味着什么,请考虑相反的情况,即未对齐的写入,其中将32位值写入到其底部两位不为零的地址。在这种情况下,处理器必须跨越边界分两部分写入。这被称为破损写入, 因为总线上的观察者可以看到此部分更新的值。1

这些话来自多处理器普及之前的时代。那时,读写中断的观察者很可能是ISA,VESA或PCI总线上的其他代理,例如磁盘控制器或视频卡。但是,我们现在生活在多核时代,因此我们需要谈论缓存和可见性。

自从开始计算以来,CPU的运行速度始终快于主内存。也就是说,计算机的性能与其存储器的性能密切相关。这称为处理器/内存间隙。为了弥合这种差距,处理器采用了将最近访问的内存存储在更靠近处理器的小型高速缓存中。2因为高速缓存也将缓冲写回主内存,而一个对齐地址的特性会变成原子遗骸, 此时该写操作发生已变得不那么确定性。3这是原子一词的第二个使用范围,该词由sync/atomic程序包实现。

在现代多处理器系统中,对主内存的写操作将在命中主内存之前在多级缓存中进行缓冲。这样做是为了隐藏主内存的等待时间,但是这样做意味着使用主内存的处理器之间的通信现在不精确。从内存读取的值可能已经被一个处理器覆盖,但是新值尚未通过各种缓存成功同步。

要解决这种歧义,需要使用内存屏障。内存写屏障操作告诉处理器它必须等待,直到其管道中所有未完成的操作(特别是写操作)都已刷新到主内存中为止。此操作还会使缓存无效

由其他处理器持有时,迫使它们直接从内存中检索新值。 读取也是如此,使用内存读取屏障来告诉处理器停止任何未完成的内存写入同步。

就Go而言,读和写内存屏障操作由程序包sync/atomic处理,特别是 分别由 atomic.Loadatomic.Store处理。

为了回答OP的问题:为了安全地在两个goroutine之间的通信通道使用内存中的值,除非使用该sync/atomic 程序包,否则数据竞态检测器会抱怨。

  1. 从历史上看,大多数处理器(但不是英特尔)都将未对齐的写入定为非法,如果尝试了未对齐的读取或写入,则会导致报错。通过消除将未对齐的负载和存储转换为存储器子系统的严格对齐要求,在晶体管价格昂贵的时候,这简化了处理器的设计。然而,今天,几乎所有的微处理器都已经发展为允许不对齐的访问,这是以性能和原子写入属性的损失为代价的。

  2. 第一台具有缓存的生产计算机是IBM System / 360 Model 85。

  3. 这过于简单。在硬件级别,需要将物理地址范围取消缓存以进行读取或遵循直写而不是回写语义。为了讨论同一虚拟地址空间中两个goroutine之间的内存可见性,可以安全地忽略这些细节。

  4. nitpicker的注释:从技术上讲,缓存行是无效的

  5. 即使大多数处理器允许不对齐的读写,内存上的原子操作也要求地址自然对齐,因为处理器之间的通信由高速缓存处理,通常以64字节长的高速缓存行进行操作。因此,未对齐的读取或写入可能会跨越两个高速缓存行,这将不可能在各个处理器之间进行原子同步。

相关文章

  • [译]如果对齐内存的写入是原子性的,为什么我们还需要sync/a

    原文地址:https://dave.cheney.net/2018/01/06/if-aligned-memory...

  • 结构体内存对齐

    对象内存对齐 探讨的问题 1.什么是内存对齐?2.为什么要做内存对齐?3.结构体内存对齐规则4.源码内存对齐算法 ...

  • 语言中sync()

    sync是C语言的一个库函数。调用sync可以将系统缓冲区(内存中)的数据写入到文件系统(磁盘)中。 sync的声...

  • 结构体内存对齐

    为什么要进行内存对齐 1.为了cpu读取更快使CPU的访问内存数据的速度加快,如果一个内存的数据是经过对齐的,那么...

  • 内存对齐

    内存对齐 为什么是16,而不是9呢?这就是因为内存对齐的原因 为什么需要内存对齐 计算机系统对基本数据类型的合法地...

  • 内存对齐

    为什么内存对齐计算机平台往往为了提高内存萃取效率,往往对数据进行对齐存放,如果不对数据存放进行对齐,会在存取效率上...

  • OC底层原理三:内存对齐分析

    获取内存大小 上一篇我们简单的提了下内存字节对齐以及为什么要内存字节对齐,那么我们首先看下有什么方式可以获取内存大...

  • atomic不能足够安全(effective objective

    atomic使用了原子性,保证了线程安全,事实真的是这样吗?nonatomic的内存管理语义是非原子性的,非原子性...

  • 5. 监视和ZooKeeper操作

    ZooKeeper中的写入(write)操作是原子性和持久性的。 写入到大多数ZooKeeper服务器上的持久性存...

  • JAVA面试

    volatile: 保证可见性 不保证原子性 禁止指令重排序 为什么不保证原子性?因为当一个两个线程一起写入工作内...

网友评论

      本文标题:[译]如果对齐内存的写入是原子性的,为什么我们还需要sync/a

      本文链接:https://www.haomeiwen.com/subject/ikfjaktx.html