多线程编程,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.07.23 洛谷P4513 小白逛公园(线段树)
传送门 线段树常规操作了解一下. 单点修改维护区间最大连续和. 对于一个区间,维护区间从左端点开始的连续最大和,从右端点开始的连续最大和,整个区间最大和,区间和. 代码如下: #include< ...
- SQL之mysql常用操作语句(入门级)
1.进入数据库: mysql -u root -p mysql -h localhost -u root -p database_name 2.列出数据库 show databases; 3.选择数据 ...
- ArcGIS Desktop Python add-ins 插件类型
Python可以在ArcGIS 桌面程序中创建如下的插件类型: 插件类型 描述 按钮(button) 是一个简单功能定制形式,可以在点击情况下执行一些业务逻辑.它会执行一个或一系列的动作.按钮可以放在 ...
- MarkdownPad 2.x破解下载
Markdown是一种轻量级的标记语言,目前有不少Markdown编辑器,其他的编辑器,诸如:Notepad++.Sublime Text 2也通过插件添加了支持.Markdown的特点就是易读易写, ...
- webuploader 文件上传总结
$(function() { /** * 初始化Web Uploader */ var uploader = WebUploader.create({ swf : '../mobile/Uploade ...
- Spring 、 CXF 整合 swagger 【试炼】
官网:http://swagger.io/ http://swagger.io/specification/ 上面就是描述了什么是 SWAGGER OBJECT 2. 如何用jax-rs 注解方式产生 ...
- WPF 嵌入字体文件
官方说明文档:将字体与应用程序一起打包 https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/advanced/packaging-fonts-w ...
- crosss compile VLC with OpenMAX on ARM board(RockChip RK3399),in order to use Hard Acceleration when decode video
reference:http://www.x90x90x90.com/en/raspberry-pi-3-howto-compile-vlc-with-hardware-acceleration/ 1 ...
- Java中HTTP通信
Java自带的get.post请求: get请求方式: package com.java; import java.io.BufferedReader; import java.io.IOExcept ...
- 论文笔记(2)-Dropout-Regularization of Neural Networks using DropConnect
这篇paper使用DropConnect来规则化神经网络.dropconnect和dropout的区别如下图所示.dropout是随机吧隐含层的输出清空,而dropconnect是input unit ...