多线程编程,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是如何解决多线程内存访问问题的的更多相关文章
- 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥) 介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...
- Java多线程编程(一)Java多线程技能
一.进程和多线程的概念以及线程的优点 打开Windo任务管理器可以看到很多正在运行着的exe程序,完全可以将运行在内存中的exe文件理解成进程,进程是受操作系统管理的基本运行单元. 线程可以理解成在进 ...
- Java多线程编程核心技术---对象及变量的并发访问(二)
数据类型String的常量池特性 在JVM中具有String常量池缓存的功能. public class Service { public static void print(String str){ ...
- 《java多线程编程核心技术》(一)使用多线程
了解多线程 进程和多线程的概念和线程的优点: 提及多线程技术,不得不提及"进程"这个概念.百度百科对"进程"的解释如下: 进程(Process)是计算机中的程序 ...
- java多线程编程核心技术(一)--多线程技能
1.进程和线程的概念 1.进程:进程是操作系统的基础,是一次程序的执行,是一个程序及其数据在处理机上顺序执行时所发生的活动,是程序在一个数据集合上运行的过程,他是系统进行资源分配和调度的一个独立单位. ...
- Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可以看作是Unix进程的表亲,同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间, ...
- Java多线程编程核心 - 对象及变量的并发访问
1.什么是“线程安全”与“非线程安全”? “非线程安全”会在多个线程对同一对象总的实例变量进行并发访问时发生,产生的后果是“脏读”,也就是取到的数据其实是被更改过的. “线程安全”是以获得的实例变量的 ...
- Java多线程编程核心技术---对象及变量的并发访问(一)
synchronized同步方法 "非线程安全"其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是"脏读",也就是渠道的数据其实是被更改 ...
- Linux下的多线程编程
1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,但是在一个进程(proces ...
随机推荐
- 2018.09.01 hdu4405 Aeroplane chess (期望dp)
传送门 期望dp简单题啊. 不过感觉题意不太对. 手过了一遍样例发现如果有捷径必须走. 这样的话就简单了啊. 设f[i]" role="presentation" sty ...
- memmove、memcpy、strcpy、memset的实现
memmove.memcpy.strcpy.memset 原型为: void *memmove( void* dest, const void* src, size_t count ); char* ...
- Linux设置开机启动项
第一种方式:ln -s 建立启动软连接 在Linux中有7种运行级别(可在/etc/inittab文件设置),每种运行级别分别对应着/etc/rc.d/rc[0~6].d这7个目录 Tips:/etc ...
- spring boot使用java读取配置文件,DateSource测试,BomCP测试,AnnotationConfigApplicationContext的DataSource注入
一.配置注解读取配置文件 (1)@PropertySource可以指定读取的配置文件,通过@Value注解获取值 实例: @PropertySource(val ...
- 基于zookeeper的主备切换方法
继承CZookeeperHelper即可快速实现主备切换: https://github.com/eyjian/libmooon/blob/master/include/mooon/net/zooke ...
- Codeforces801D Volatile Kite 2017-04-19 00:30 122人阅读 评论(0) 收藏
D. Volatile Kite time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- Codeforces 706C Hard problem 2016-09-28 19:47 90人阅读 评论(0) 收藏
C. Hard problem time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...
- PHP环境的搭建及与nginx的集成
1. 去php官网下载最新稳定版(最新其实是7.0,为了兼容性,使用5.6.16) wget http://cn2.php.net/get/php-5.6.16.tar.gz/from/this/m ...
- Python学习-38.Python中的正则表达式(二)
在Python中,正则表达式还有较其他编程语言有特色的地方.那就是支持松散正则表达式了. 在某些情况,正则表达式会写得十分的长,这时候,维护就成问题了.而松散正则表达式就是解决这一问题的办法. 用上一 ...
- Visual Studio模板
转载自MSDN,此文仅作参考. http://msdn.microsoft.com/zh-cn/library/6db0hwky(VS.80).aspx 1. 如何导入“项目模板(Project Te ...