zoukankan      html  css  js  c++  java
  • 多线程编程,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

  • 相关阅读:
    Mysql之正则匹配
    定时任务之elastic-job概述
    清晰讲解LSB、MSB和大小端模式及网络字节序
    极光消息推送多环境配置
    基于TSUNG对MQTT进行压力测试-测试结果
    基于TSUNG对MQTT进行压力测试-基础概念温习
    阻塞式/非阻塞式与同步/异步的区别
    干货!Jenkins下配置findbugs、pmd及checkstyle实现代码自动检测
    jar包
    java环境变量及Eclipse自动编译问题
  • 原文地址:https://www.cnblogs.com/Gool/p/9417205.html
Copyright © 2011-2022 走看看