怎么用安卓机顶盒做网站服务器,移动网站 案例,域名估价哪个网站准确,建立网站第一步是什么刚看到这个词的时候#xff0c;我以为是白内障#xff0c;然后查了很多资料#xff0c;才理解内存屏障是干嘛的#xff0c;我就不像很多其他文章说得那么多了#xff0c;我希望我说得简单一些#xff0c;让大家看了我的文章都知道这个是怎么回事。说到内存屏障#xff0… 刚看到这个词的时候我以为是白内障然后查了很多资料才理解内存屏障是干嘛的我就不像很多其他文章说得那么多了我希望我说得简单一些让大家看了我的文章都知道这个是怎么回事。说到内存屏障我们先从CPU性能优化说起性能优化的方法一缓存CPU的速度很快到底有多快我们就用光速来比喻CPU的执行速度吧反正就是执行读写很快但是CPU速度很快内存的速度很慢怎么办这时候高速缓存出现了「先不抬杠说寄存器哈」。比如有一个变量a CPU在很长一段时间内都需要使用它如果把他放在内存里面的话每次读写的速度都很慢这样严重拖慢了CPU的执行速度。所以就出现了 缓存缓存也是分类的缓存分成了三类我简单说明下缓存同步协议MESI如果在4个CPU在各自的L1 里面都有一个变量 i 他们要把这个变量i写入到内存里面去是以哪一个为准呢这个时候就需要缓存的同步协议每个cpu对缓存里面的变量操作的时候要通知其他CPU让他们知道当前的状态。CPU不仅需要发消息给其他CPU告诉他们状态同时也要接收其他CPU发出来的状态。这样做的最终目的就是为了保证CPU对变量操作的一致性。CPU性能优化的方法二运行时指令重排指令重排是个有意思的事情如果把CPU当成是一个人的话他也是有自己的意识的存在意识的东西就会存在自己做事情的方法比如我今天要去打篮球还要去帮妈妈打酱油我是先打篮球还是先打酱油因为个人的意识不同做事情的先后顺序也存在差异。为什么出现指令重排如果有一个CPU我们假设是CPU0吧它在写缓存的的某个区块的时候发现这个缓存位置刚好被CPU1正常操作那他怎么办有两种方法一种是等待CPU1执行结束后自己再执行还有一种方法就是先去干其他的事情很明显CPU为了提高自己的性能它会选择第二种方法就是先去干其他的事情干其他的事情就出现上面描述的情况指令重排了。所以我们会有一个疑问代码是按照程序员的想法去执行的呢还是按照CPU的想法去执行的呢回答当然是需要按照程序员的意识去执行的。所以要求指令重排遵循as-if-serial语义这个是什么意思呢就是说指令重排的结果不能影响程序员预期的结果比如上面的代码重排后就会出现问题那么CPU就不能对指令进行重排。注意上面所说的as-if-serial语义针对的是单核CPU来说但是如果是下面的代码a 100;
b c;
上面两条语句不存在依赖关系它们可以进行指令重排因为重排后不会影响最后的执行结果。高速缓存和指令重排序(reordings)存在的问题缓存机制和指令重排都是为了CPU运算的性能优化。会出现两个问题。1、缓存和内存的数据并不是时实同步的同一个内存地址不同的CPU看到的内存值是不一样的。因为CPU运行速度很快假设CPU0 读 地址 0x2345 的时候值为 1这个时候CPU1向 0x2345写入了 2CPU2再读这个内存 0x2345 的值的时候发现它变成2了。所以就有问题了。出现的问题是同一个时间点上不同的CPU看到的同一个内存地址数据不一样2、我们指令重排说的as-if-serial语义只是针对单个CPU那多个CPU呢会出现什么问题看下面的例子看上面图片CPU0 要执行两条指令CPU1也要执行两条指令但是如果他们执行的先后顺序不同那么x和y的结果也将存在差异。第一种情况如下图执行顺序会导致 x 0 , y 1。第二种情况如下图执行顺序会导致 x 1y 0。第三种情况如下图执行顺序会导致 x 1,y1。结果跟程序员的预期不符合 出现的问题是多个CPU也就是我们经常所说的SMP系统下会出现结果和预期不一致的问题最后说内存屏障Memory Barrier内存屏障就是用来解决上面两个问题的。这个是CPU厂商来搞定的。写内存屏障Store Memory Barrier 写内存屏障的意思就是在写内存的后面加入指令 Store Barrier 如果CPU有读的也有写的加了这条指令就保证先执行写入而不去做指令重排这种显示调用可以让其他线程看到。其他线程会等这个执行结束后再去操作既然是等待那也是降低性能的好吧降低性能也是没有办法的事情了。就拿上面的 图片来说明A 1 B 1 这两个是写操作我们加上写内存屏障即使其他CPU有读的指令我们需要等待这个写完成后再进行读操作。读内存屏障 Load Memory Barrier 在读指令之前插入Load Barrier可以让高速缓存中的数据失效强制从内存加载最新的数据让CPU缓存和主内存保持一致避免了缓存导致的一致性问题。void executedOnCpu0() {value 10;/*在更新数据之前必须将所有存储缓存store buffer中的指令执行完毕。*/storeMemoryBarrier();finished true;
}
void executedOnCpu1() {while(!finished);/*在读取之前将所有失效队列中关于该数据的指令执行完毕。*/loadMemoryBarrier();assert value 10;
}
总结CPU为了性能发明了缓存和指令重排但是又因为缓存和指令重排出现了新的问题因为新的问题出现聪明的人类又发明了内存屏障之所谓兵来将挡水来土掩就是这个道理。文章是整理了自己看到资料的很多见解后续会发新的文章进一步讲解当然了或者也会不发我就是一只漂亮的鸽子我鸽呀鸽呀鸽祝大家周末愉快。扫码或长按关注回复「 篮球的大肚子」进入技术群聊