
_START_ARTICLE_
内存屏障
_START_PARAGRAPH_
内存屏障（英语：Memory barrier），也称内存栅栏，内存栅障，屏障指令等，是一类同步屏障指令，它使得CPU 或编译器在对内存进行操作的时候, 严格按照一定的顺序来执行, 也就是说在memory barrier 之前的指令和memory barrier之后的指令不会由于系统优化等原因而导致乱序。_NEWLINE_大多数现代计算机为了提高性能而采取乱序执行，这使得内存屏障成为必须。  _NEWLINE_语义上，内存屏障之前的所有写操作都要写入内存；内存屏障之后的读操作都可以获得同步屏障之前的写操作的结果。因此，对于敏感的程序块，写操作之后、读操作之前可以插入内存屏障。
_START_SECTION_
举例
_START_PARAGRAPH_
当驱动程序运行下列动作时，如果处理器的写入指令out-of-order，使得数据还没有写入存储器，硬件模块就被触发开始动作，就会产生错误的行为。_NEWLINE_  寫資料到記憶體, 稍後硬體模塊會存取這一筆資料_NEWLINE_  // 此處需要內存屏障_NEWLINE_  觸發硬體模塊開始處理資料
_START_SECTION_
多线程编程与内存可见性
_START_PARAGRAPH_
多线程程序通常使用高层程序设计语言中的同步原语，如Java与.NET Framework，或者API如pthread或Windows API。因此一般不需要明确使用内存屏障。_NEWLINE_内存可见性问题，主要是高速缓存与内存的一致性问题。一个处理器上的线程修改了某数据，而在另一处理器上的线程可能仍然使用着该数据在专用cache中的老值，这就是可见性出了问题。解决办法是令该数据为volatile属性，或者读该数据之前执行内存屏障。
_START_SECTION_
乱序执行与编译器重排序优化的比较
_START_PARAGRAPH_
C与C++语言中，volatile关键字意图允许内存映射的I/O操作。这要求编译器对此的数据读写按照程序中的先后顺序执行，不能对volatile内存的读写重排序。因此关键字volatile并不保证是一个内存屏障。_NEWLINE_对于Visual Studio 2003，编译器保证对volatile的操作是有序的，但是不能保证处理器的乱序执行。因此，可以使用InterlockedCompareExchange或InterlockedExchange函数。_NEWLINE_对于Visual Studio 2005及以后版本，编译器对volatile变量的读操作使用acquire semantics，对写操作使用release semantics。
_START_SECTION_
编译器内存屏障
_START_PARAGRAPH_
编译器会对生成的可执行代码做一定优化，造成乱序执行甚至省略（不执行）。gcc编译器在遇到内嵌汇编语句：_NEWLINE_asm volatile("" ::: "memory");_NEWLINE_将以此作为一条内存屏障，重排序内存操作。即此语句之前的各种编译优化将不会持续到此语句之后。也可用内建的__sync_synchronize_NEWLINE_Microsoft Visual C++的编译器内存屏障为：_NEWLINE__ReadWriteBarrier() MemoryBarrier()_NEWLINE_Intel C++编译器的内存屏障为：_NEWLINE___memory_barrier()