指令级并行原理

多线程编程出现的背景

计算机的运算速度远远大于存储和通讯速度,导致cpu大部分时间里都处于等待其他资源的状态,多线程就是为了充分利用计算机处理器的能力,解决这个问题
一个服务端同时对多个客户端提供服务则是另一个具体的并发应用场景,衡量一个服务性能的高低好坏,每秒事务处理数是最重要的指标之一,它代表着一秒内服务端平均能响应的请求总数,而TPS值与程序的并发能力又有非常密切的关系.对于计算量相同的任务,程序线程并发协调得有条不紊,效率自然就会越高;反之,线程之间频繁阻塞甚至死锁,将会大大降低程序的并发能力.

计算机硬件效率与缓存一致性

由于计算机的存储设备与处理器的运算速度相差几个数量级,现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存来作为内存与处理器之间的缓冲;将运算需要使用到的数据从主内存中复制到缓存中,让运算能快速进行,当运算结束后再从缓存同步回内存之中,这样处理器就无须等待缓慢的内存读写了.
多处理器系统中,每个处理器都有自己的高速缓存,而它们又共享一主内存(Main Memory).当多个处理器的运算任务都涉及同一块主内存区域时,将导致各自的缓存数据不一致的情况.各个处理器访问缓存时都遵循一些缓存一致性协议,当读写时要根据协议来进行操作.
除此之外,为了使得处理器内部的运算单元能尽量被充分利用,处理器可能会对输入代码进行乱序执行优化,处理器会在计算之后将乱序执行的结果重组,保证该结果与顺序执行的结果一致,类似于java即时编译器中的指令重排序优化
java虚拟机规范试图定义一种java内存模型来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让java程序在各种平台下都能达到一致性的并发效果,而C++直接使用操作系统的内存模型,导致程序在不同平台运行出现问题
 

缓存一致性协议

  1. 名词
    1. Clock Cycle Time 主频的概念大家接触的比较多,而 CPU 的 Clock Cycle Time(时钟周期时间),等于主频的倒数,意思是 CPU 能 够识别的最小时间单位,比如说 4G 主频的 CPU 的 Clock Cycle Time 就是 0.25 ns,作为对比,我们墙上挂钟的 Cycle Time 是 1s 例如,运行一条加法指令一般需要一个时钟周期时间
      CPI 有的指令需要更多的时钟周期时间,所以引出了 CPI (Cycles Per Instruction)指令平均时钟周期数
      IPC
      IPC(Instruction Per Clock Cycle) 即 CPI 的倒数,表示每个时钟周期能够运行的指令数
       
      程序的 CPU 执行时间,即我们前面提到的 user + system 时间,可以用下面的公式来表示
       
      程序 CPU 执行时间 = 指令数 * CPI * Clock Cycle Time
  1. 鱼罐头的故事
    1. 加工一条鱼需要 50 分钟,只能一条鱼、一条鱼顺序加工...
      notion image
      可以将每个鱼罐头的加工流程细分为 5 个步骤:
      • 去鳞清洗 10分钟
      • 蒸煮沥水 10分钟
      • 加注汤料 10分钟
      • 杀菌出锅 10分钟
      • 真空封罐 10分钟
      notion image
       
      即使只有一个工人,最理想的情况是:他能够在 10 分钟内同时做好这 5 件事,因为对第一条鱼的真空装罐,不会影响对第二条鱼的杀菌出锅...
       
  1. 指令重排序优化
    1.  
      事实上,现代处理器会设计为一个时钟周期完成一条执行时间最长的 CPU 指令。为什么这么做呢?可以想到指令 还可以再划分成一个个更小的阶段,例如,每条指令都可以分为: 取指令 - 指令译码 - 执行指令 - 内存访问 - 数据写回 这 5 个阶段
      notion image
      在不改变程序结果的前提下,这些指令的各个阶段可以通过重排序和组合来实现指令级并行,这一技术在 80's 中 叶到 90's 中叶占据了计算架构的重要地位
      指令重排的前提是,重排指令不能影响结果,例如
       
      // 可以重排的例子 int a = 10; // 指令1 int b = 20; // 指令2 System.out.println( a + b ); // 不能重排的例子 int a = 10; // 指令1 int b = a - 5; // 指令2
       
       
       
      支持流水线的处理器
      现代 CPU 支持多级指令流水线,例如支持同时执行 取指令 - 指令译码 - 执行指令 - 内存访问 - 数据写回 的处理 器,就可以称之为五级指令流水线。这时 CPU 可以在一个时钟周期内,同时运行五条指令的不同阶段(相当于一 条执行时间最长的复杂指令),IPC = 1,本质上,流水线技术并不能缩短单条指令的执行时间,但它变相地提高了 指令地吞吐率
      notion image
      SuperScalar 处理器
      大多数处理器包含多个执行单元,并不是所有计算功能都集中在一起,可以再细分为整数运算单元、浮点数运算单 元等,这样可以把多条指令也可以做到并行获取、译码等,CPU 可以在一个时钟周期内,执行多于一条指令,IPC > 1