美文网首页
12.4 计算机组成、MESI协议、名词解释

12.4 计算机组成、MESI协议、名词解释

作者: 奋斗_2339 | 来源:发表于2020-05-09 14:51 被阅读0次

1.计算机组成

计算器组成.png

2.多核CPU:一个CPU中有多个核心

一个双核CPU.png

3.缓存行 Cache line伪共享

  • 缓存是为了降低CPU和主存速度差异,采用的解决办法。
  • 每个缓存里面都是由缓存行组成的,缓存系统中是以缓存行(cache line)为单位存储的,常见的缓存行大小为64个字节
  • 当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享(PS:采用缓存行对齐来解决伪共享问题)
    缓存行伪共享.png
      在core1上运行的线程修改变量X,同时core2上的线程修改变量Y。不幸的是,这两个变量在同一个缓存行中。每个线程都要去竞争缓存行的所有权来修改变量。如果core1获得了所有权,缓存子系统将会使core2中对应的缓存行失效。这样来来回回读取主存数据,大大影响了性能。如果互相竞争的核心位于不同的插槽,就要额外横跨插槽连接
public class Test_CacheLine{
    //使用缓存行对齐来解决伪共享
    private static class Padding{
        public long p1,p2,p3,p4,p5,p6,p7;
    }
    
    private static class T /**extends Padding**/{
        public volatile long x = 0L;
    }
    //使对象在同一个缓存行
    public static T[] arr = new T[2];
    
    static {
        arr[0] = new T();
        arr[1] = new T();
    }
    
    public static void main(String[] args) throws Exception{
        Thread t1 = new Thread(() ->{
            for(long i=0; i<1000_0000L; i++){
                arr[0].x = i;
            }
        });
        
        Thread t2 = new Thread(() ->{
            for(long i=0; i<1000_0000L; i++){
                arr[1].x = i;
            }
        });
        
        final long start = System.nanoTime();
        t1.start();
        t2.start();
        
        t1.join();
        t2.join();
        System.out.println((System.nanoTime() - start)/100_10000);
    }
}

参考链接:https://www.jianshu.com/p/e338b550850f

4.MESI 协议(X86):让多核 CPU 的高速缓存保持一致

  • M: 代表已修改(Modified)
  • E: 代表独占(Exclusive)
  • S: 代表共享(Shared)
  • I: 代表已失效(Invalidated)
    PS: 缓存锁实现之一,有些无法被缓存的数据或者跨越多个缓存行的数据,必须使用总线锁。

  要解决缓存一致性问题,首先解决核心之间的数据传播, 最常见的一种解决方案就是采用总线嗅探,这个策略,本质上就是把所有的读写请求都通过总线(Bus)广播给所有的 CPU 核心,然后让各个核心去 “嗅探” 这些请求,再根据自己的情况进行响应。
  MESI 协议,是一种叫作写失效(Write Invalidate)的协议。在写失效协议里,只有一个 CPU 核心负责写入数据,其他的核心,只是同步读取到这个写入。在这个 CPU 核心写入 Cache 之后,它会去广播一个 “失效” 请求告诉所有其他的 CPU 核心。其他的 CPU 核心,只是去判断自己是否也有一个 “失效” 版本的Cache line,然后将状态修改成失效状态
  相对于写失效协议,还有一种叫作写广播(Write Broadcast)的协议。在那个协议里,一个写入请求广播到所有的 CPU 核心,同时更新各个核心里的 Cache

写失效.png
写广播.png

参考链接:https://blog.csdn.net/qyf__123/article/details/100904595

5.线程和进程的概念

  • 线程是CPU执行的基本单位
  • 进程是CPU资源分配的基本单位

8.问题

  • 8.1 一个单核CPU+多线程情况下,变量虽然保证了可见性(使用同样的缓存行),但是仍然会出现并发问题。
int i = 1;
if(i == 1){ //B线程进入判断,i仍然是1,执行后续代码
   i++; //A线程准备执行该条指令时,进行了线程切换,即B线程执行
  System.out.println(i);
}
多线程下,打印了多次i值,即出现了并发问题。
  • 8.2 cpu线程数和java线程数有直接关系吗?
    操作系统线程(CPU线程)其实是操作系统利用CPU的中断去切换执行的指令片段模拟出来。
    没有直接关系,正如上面所说,cpu采用分片机制执行线程,给每个线程划分很小的时间颗粒去执行,但是真正的项目中,一个程序要做很多的的操作,
读写磁盘、数据逻辑处理、出于业务需求必要的休眠等等操作,当程序在进行I/O操作的时候,线程是阻塞的,线程由运行状态切换到等待状态,此时
cpu会做上下文切换,以便处理其他的程序;当I/O操作完成后,cpu 会收到一个来自硬盘的中断信号,并进入中断处理例程,手头正在执行的线程因此被
打断,回到 ready 队列。而先前因 I/O 而waiting 的线程随着 I/O 的完成也再次回到就绪队列,这时 cpu 可能会选择它来执行。
(PS:摘抄于网络)

相关文章

网友评论

      本文标题:12.4 计算机组成、MESI协议、名词解释

      本文链接:https://www.haomeiwen.com/subject/zgpfnhtx.html