AtomicPointer是LevelDB中的一个基础数据结构,其核心代码只有寥寥10来行。
但是,为了理解这10来行代码,却需要十分扎实的CPU架构、操作系统、编译器、C++11知识。
为了搞明白其背后的原理,同时加深理解,我准备从以下几点着手,一步步抽丝剥茧:
常用的编程语言中,均提供了“顺序执行“的语义。
就是,单个执行流中的语句,我们总可以将其理解成“逐条执行”。
那么,“乱序执行”又从何谈起呢?
为了理解“乱序执行”,我们需要拨开高级语言的抽象,深入到计算机组成原理中。
以“x = 42”为例,其对应的汇编指令一般包含这几步操作:
1)从x的内存地址加载数据到内存中;
2)修改寄存器中的值;
3)将寄存器中的数据,回写到内存中;
因此,即便是简单的赋值操作,也可能不是Atomic操作(当然,这也取决于具体的CPU架构)。
赘述下就是,两条C语句在被编译成汇编指令时,产生远不止两条的汇编指令。
这些汇编指令,被编译器以某种形式打乱,糅杂在一起,从而模糊了两条C语句之间的原有界限。
当然,打乱也是要“限度”的,总不能改变代码原有的语义,不然我们写代码就没有意义了;
那么,限度是什么?就是单个线程运行这段打乱后的汇编指令,就跟顺序执行C语言一样;
但是,并不保证其他线程能看到和我一致的"顺序执行“效果(如果这些变量是共享变量);
刚刚说到的乱序是编译器一级的。
然而,现代CPU为了进一步压榨性能,进一步将"单条汇编指令"切割成多条“Micro Code",并加入了"pipeline"等技术。
因而,即便是汇编指令,也同样面临了高级语言一样的“乱序”问题;
那什么是Memory Barrier呢?
首先,我们来看下Wikipedia中的解释
A memory barrier, is a type of barrier instruction that causes a CPU or compiler to enforce an ordering constraint on memory operations issued before and after the barrier instruction. This typically means that operations issued prior to the barrier are guaranteed to be performed before operations issued after the barrier.
从上段文字中,可知内存屏障
在上一小节中,我们已经铺垫了“乱序执行”的概念。
因而,我们能自然而然地想到,Memory Barrier是为了消除“乱序执行”的负面影响。
上面说的这些,都比较晦涩。为此,我们来看一个具体的例子。
在这个例子中,一个线程作为“发令员”,发出"起跑"的信号;
另一个线程作为”运动员“,等待”起跑“信号。
// x = 10; toRun = false; 初始值
x = 42;
toRun = true; // 发出“起跑”的信号
while (toRun == false) // 等待“起跑”信号
;
print x;
根据代码字面的意思,我们可能觉得会输出“x = 42”。但是,实际的结果可能并不会如你所愿。
现在,我们举两个例子:
Case 1:由于“乱序执行”,“x = 42”的赋值操作可能发生在“toRun = true;”之后,导致x的值非我们所愿;
Case 2: 由于“乱序执行”,“print x”语句在while语句之前就已经加载了变量x的值,导致x的值非我们所愿;
所以,上面讲了那么多,总结起来,其实很简单:
在多线程环境下,我们无法依赖单个执行流内语句之间的先后顺序,来确保多个执行流之间的”happens-before“关系。
语句之间的先后顺序 != happens-before
Platform-Specific的AtomicPointer实现代码如下:
class AtomicPointer {
private:
void* rep_;
public:
/* 省略无关代码 */
inline void* Acquire_Load() const {
void* result = rep_;
MemoryBarrier();
return result;
}
inline void Release_Store(void* v) {
MemoryBarrier();
rep_ = v;
}
};
inline void MemoryBarrier() {
__asm__ __volatile__("" : : : "memory");
}
todo...
https://en.wikipedia.org/wiki/Memory_barrier
Memory Barriers: a Hardware View for Software Hackers