多线程编程,CPU是如果解决多线程内存访问问题的
Posted gool
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程编程,CPU是如果解决多线程内存访问问题的相关的知识,希望对你有一定的参考价值。
CPU对内存变量的修改是先读取内存数据到CPU Cache中,然后再由CPU做运算,运算完成后继续写入到内存中
在单核CPU中,这完全没有问题,然而在多核CPU中,每一个CPU核心都拥有自己独立的Cache
此时同时访问同一个内存地址时,将会把内存值复制到多个CPU的Cache中
此时如果对Cache中的值进行修改数据就将会不一致,写入到内存时,内存中的数据就将会达不到预期值
为了解决这一个问题,早期CPU中,采用了总线LOCK的办法,某个CPU要对内存操作的时候,总线进行LOCK,直到操作完成再UNLOCK
总线包含了许多设备的控制,LOCK将会大大降低资源处理的速度,于是intel提出了MESI协议
intel自从奔腾之后就开始引入MESI协议,目前许多CPU都在使用该协议的变种
MESI中,一个Cache被称为Row,不同CPU Cache中同一个内存地址的副本,他们的row都是相同的
Row有4种状态,他们分别是
状态 |
描述 |
M(Modified) |
这行数据有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。 |
E(Exclusive) |
这行数据有效,数据和内存中的数据一致,数据只存在于本Cache中。 |
S(Shared) |
这行数据有效,数据和内存中的数据一致,数据存在于很多Cache中。 |
I(Invalid) |
这行数据无效。 |
Exclusive独占
M修改状态
每个CPU在读写自己的Cache row的同时,也会监听其他CPU的Cache row
当只有一个CPU拥有内存副本时,设置为E(Exclusive)状态
当第二个CPU读取内存副本时,设置为S(Shared)状态
当其他CPU修改内存副本时,设置为I(Invalid)状态
当前CPU修改内存副本时,设置为M(Modified)状态
每个CPU Cache row都有自己的一个状态
MESI状态之间的迁移过程如下:
当前状态 |
事件 |
行为 |
下一个状态 |
I(Invalid) |
Local Read |
如果其它Cache没有这份数据,本Cache从内存中取数据,Cache line状态变成E; 如果其它Cache有这份数据,且状态为M,则将数据更新到内存,本Cache再从内存中取数据,2个Cache 的Cache line状态都变成S; 如果其它Cache有这份数据,且状态为S或者E,本Cache从内存中取数据,这些Cache 的Cache line状态都变成S |
E/S |
Local Write |
从内存中取数据,在Cache中修改,状态变成M; 如果其它Cache有这份数据,且状态为M,则要先将数据更新到内存; 如果其它Cache有这份数据,则其它Cache的Cache line状态变成I |
M |
|
Remote Read |
既然是Invalid,别的核的操作与它无关 |
I |
|
Remote Write |
既然是Invalid,别的核的操作与它无关 |
I |
|
E(Exclusive) |
Local Read |
从Cache中取数据,状态不变 |
E |
Local Write |
修改Cache中的数据,状态变成M |
M |
|
Remote Read |
数据和其它核共用,状态变成了S |
S |
|
Remote Write |
数据被修改,本Cache line不能再使用,状态变成I |
I |
|
S(Shared) |
Local Read |
从Cache中取数据,状态不变 |
S |
Local Write |
修改Cache中的数据,状态变成M, 其它核共享的Cache line状态变成I |
M |
|
Remote Read |
状态不变 |
S |
|
Remote Write |
数据被修改,本Cache line不能再使用,状态变成I |
I |
|
M(Modified) |
Local Read |
从Cache中取数据,状态不变 |
M |
Local Write |
修改Cache中的数据,状态不变 |
M |
|
Remote Read |
这行数据被写到内存中,使其它核能使用到最新的数据,状态变成S |
S |
|
Remote Write |
这行数据被写到内存中,使其它核能使用到最新的数据,由于其它核会修改这行数据, 状态变成I |
I |
以上是关于多线程编程,CPU是如果解决多线程内存访问问题的的主要内容,如果未能解决你的问题,请参考以下文章
Linux 操作系统原理 — 进程管理 — NUMA 架构中的多线程调度开销与性能优化
Java多线程,线程安全与不安全的理解,程序的多线程并发编程的基础概念,进程与线程的区别是什么