当前位置:  开发笔记 > 编程语言 > 正文

什么是记忆围栏?

如何解决《什么是记忆围栏?》经验,为你挑选了3个好方法。

使用显式内存栅栏是什么意思?



1> Gwaredd..:

为了提高性能,现代CPU通常不按顺序执行指令以最大限度地利用可用的硅(包括存储器读/写).由于硬件强制执行指令完整性,因此您不会在单个执行线程中注意到这一点.但是,对于具有易失性内存的多线程或环境(例如,内存映射I/O),这可能会导致不可预测的行为.

内存栅栏/屏障是一类指令,表示内存读/写按您期望的顺序发生.例如,"完全栅栏"表示在栅栏之后的栅栏之前进行所有读/写操作.

注意内存栅栏是硬件概念.在更高级别的语言中,我们习惯于处理互斥锁和信号量 - 这些很可能是使用低级别的内存栅栏来实现的,并且不需要明确使用内存屏障.使用内存屏障需要仔细研究硬件架构,并且在设备驱动程序中比应用程序代码更常见.

CPU重新排序与编译器优化不同 - 尽管伪像可以类似.如果可能导致不良行为(例如在C中使用volatile关键字),则需要采取单独的措施来停止编译器重新排序指令.


我不认为volatile足以阻止编译器重新排序; AFAIK它只确保编译器不能缓存变量值.Linux内核使用gcc扩展(__asm__ __volatile __("":::"memory"))来创建完整的编译器优化障碍.
true,volatile不是线程感知的,但您可以使用它来阻止编译器应用某些优化 - 这与fences无关;)
有关.net中volatile关键字的有趣读物可以在这里找到http://www.albahari.com/threading/part4.aspx#_NonBlockingSynch该网站包含很多关于c#中线程的有用信息
(.NET CLR)易失性读取是获取隔离区,写入是释放隔离区。互锁的操作已满,MemoryBarrier方法也已满。

2> CesarB..:

将我的答案复制到另一个问题,处理器为优化代码做了哪些技巧?:

最重要的一个是内存访问重新排序.

如果没有内存屏障或序列化指令,处理器可以自由重新排序内存访问.某些处理器架构限制了它们可以重新排序的程度; Alpha被认为是最弱的(即可以重新排序最多的那个).

可以在Linux内核源文档的Documentation/memory-barriers.txt中找到对该主题的非常好的处理.

大多数情况下,最好使用编译器或标准库中的锁定原语; 这些都经过了充分的测试,应该具备所有必要的内存障碍,并且可能已经非常优化(优化锁定原语很棘手;即使是专家也可能有时会弄错它们).



3> peterchen..:

根据我的经验,它指的是一个内存屏障,它是一个指令(显式或隐式),用于同步多个线程之间的内存访问.

问题发生在现代侵略性编译器的组合中(它们具有重新排序指令的惊人自由,但通常对您的线程一无所知)和现代多核CPU.

对这个问题的一个很好的介绍是" '双重检查锁定'声明 ".对于许多人来说,这是一个叫醒龙的警钟.

隐含的完整内存屏障通常包含在平台线程同步例程中,它涵盖了它的核心.但是,对于无锁编程和实现自定义轻量级同步模式,您通常只需要屏障,甚至只需要单向屏障.

推荐阅读
mobiledu2402852357
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有