编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句 的执行顺序。
指令级并行的重排序。现代处理器采用了指令级并行技术(Instruction-Level Parallelism,ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应 机器指令的执行顺序。
内存系统的重排序。由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上 去可能是在乱序执行。
******************************************************************
StoreBuffer
cpu用来写内存的缓存区,不用每次都去写内存而是可以先不停的干事情。毕竟写内存需要等待,cpu只想一直做事情不想等待。可以批量一起写
优点:
可以保证core内的指令流水线持续运行,
它可以避免由于处理器停顿下来等待向内存写入数据而产生的延迟。
通过以批处理的方式刷新写缓冲区,以及合并写缓冲区中对同一内存地址的多次写,可以减少对内存总线的占用。
缺点:
每个处理器上的写缓冲区,仅对它所在的处理器可见。这个特性会对内存操作的执行顺序产生重要的影响:处理器对内存的写操作的执行顺序,不一定与内存实际发生的写操作顺序一致!
******************************************************************
Invalidate Queue
cpu在做事情的时候 ,别的cpu通知说数据需要更新,但是我不想管,你们把通知都放这个队列里面我一会一起看。
这样会导致使用旧的数据
优点:
正在处理的事情不中断
缺点:
处理器对内存的读操作的执行顺序,不一定与内存实际发生的写操作顺序一致!使用已经过期的数据,而不是最新的。
在两个CPU同时运行的情况下,CPU0自身视角来说,没有重排发生,一切都那么自然,但是CPU1却看到CPU0发生了重排(reordering memory)。这就是内存系统重排序。
******************************************************************
store buffer 和 Invalidate Queue 带来的乱序如何解决?
CPU通常提供了内存屏障指令,来解决这样的乱序问题。读屏障,清空本地的invalidate queue,保证之前的所有load都已经生效;写屏障,清空本地的store buffer,使得之前的所有store操作都生效。通俗来说就是两点:
写屏障:保证把更新写到内存
读屏障:保证从内存读取最新数据
————————————————
版权声明:本文为CSDN博主「程序一逸」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/BASK2311/article/details/128528183
浙公网安备 33010602011771号