弗林(Flynn)于1972年提出了计算平台的Flynn分类法,根据指令流和数据流的不同组织方式,把计算机系统的结构分为以下四类:
指令流(Instruction stream)是指机器执行的指令序列;数据流(data stream)是指指令流调用的数据序列,包括输入数据和中间结果。
1、 单指令流单数据流(Single Instruction stream Single Data stream,SISD)
SISD是传统的串行计算机,硬件不支持任何形式的并行计算,所有的指令都是串行执行,在某个时钟周期内,CPU只能处理一个数据流,这种机器被称作单指令流单数据流机器。
早期的计算机都是SISD机器,如:冯诺.依曼架构、IBM 、PC机等。
2、 单指令流多数据流(Single Instruction stream Multiple Data stream ,SIMD)
SIMD是采用一个指令流处理多个数据流,这类机器在数字信号处理、图像处理、以及多媒体信息处理等领域非常有效。
Intel处理器实现的MMXTM、SSE(Streaming SIMD Extensions)、SSE2及SSE3扩展指令集,都能在单个时钟周期内处理多个数据单元。
现在用的单核计算机基本上都属于SIMD机器。
3、 多指令流单数据流(Multiple Instruction stream Single Data stream ,MISD)
MISD是采用多个指令流来处理单个数据流。
实际情况中,多指令流处理多数据流才是更有效的方法, MISD只是作为理论模型出现,没有投入到实际应用之中。
4、 多指令流多数据流(Multiple Instruction stream Multiple Data stream,MISD)
MIMD机器可以同时执行多个指令流,这些指令流分别对不同数据流进行操作。
当前多核计算平台就属于MIMD的范畴,如:Intel和AMD的多核处理器等都属于MIMD。
1、每个时钟周期内可以执行的指令数(IPC:Instruction per Clock);
2、处理器的主频;
IPC(Instruction per Clock)
频率和IPC真正影响CPU性能, CPU性能判断标准应该是:CPU性能 = IPC(CPU每一时钟周期内所执行的指令多少)×频率(MHz时钟速度)
如何提高CPU的指标?
1、提供IPC:多核芯;
2、提高主频:受功耗限制,提升空间有限;
多个CPU和多核CPU架构多个CPU
多核CPU
多个CPU(物理),CPU通过总线进行通信,效率比较低;
多核CPU,不同的核通过L2 cache进行通信,存储和外设通过总线与CPU通信;
CPU的缓存CPU缓存是位于CPU与内存之间的临时数据交换器,它的容量比内存小,但交换速度比内存要快得多;CPU缓存一般直接跟CPU芯片集成或位于主板总线互连的独立芯片上。
随着多核CPU的发展,CPU缓存通常分成了三个级别:L1,L2,L3。级别越小越接近CPU,速度更快,同时也代表着容量越小。
L1 是一级缓存,最接近CPU的, 它容量最小(如:32K),速度最快,每个核上都有一个 L1 缓存,L1 缓存每个核上实际有两个 L1 缓存, 一个用于存数据的 L1d Cache(Data Cache),一个用于存指令的 L1i Cache(Instruction Cache)。
L2是二级缓存,缓存大一些(如:256K),速度要慢一些, 一般情况下每个核上都有一个独立的L2 缓存;
L3 缓存是三级缓存中最大的一级(如:3MB),同时也是最慢的一级, 在同一个CPU插槽之间的核共享一个 L3 缓存。
CPU读取数据过程,先在最快的缓存中找数据,如果缓存没有命中(Cache miss),则往下一级找, 直到三级缓存都找不到时,向内存要数据。一次次地未命中,代表获取数据消耗的时间越长。
计算过程,程序以及数据被加载到主内存;指令和数据被加载到CPU的高速缓(寄存器);CPU执行指令,把结果写到高速缓存(寄存器);高速缓存(寄存器)中的数据写回主内存。
按与CPU远近来看,关系是: CPU-->寄存器-->缓存-->内存-->硬盘
对称多处理器(Symmetric Multi-processor,SMP)多核硬件结构中,内存对多个CPU核是共享的,CPU核一般都是对称的,因此多核属于共享存储的对称多处理器。
在多核硬件结构中,如果要充分发挥硬件的性能,必须要采用多线程(或多进程)执行,使得每个CPU核在同一时刻都有线程在执行。
多核CPU系统中的编程和多个CPU的SMP系统的编程模型是一致的,都属于共享存储的编程模型。
进程与进程调度Linux的进程(线程)
Linux和其它OS之间有个很大的不同,没有严格定义的线程(thread),在Linux中,process(进程)可以当作线程,Linux有两种process,一种为独立的有自己的地址空间,资源列表,代码等;另外一种是和其它process共享一个地址空间,资源列表等;
Linux(2.6)系统中,每个核(core)都拥有一个运行队列,运行队列中的task(进程/线程)按照CFS调度算法进行调度。核(core)之间,为了实现多核的负载均衡,会把一个任务(Linux进程)从负载高的核迁移到负载低的核。
多核CPU进行调度
在多核条件下多个CPU和执行core存在,多个程序可以真正的同时执行,这时又会产生单核时的冲突(原子操作),2个进程会同时访问一个数据或者内存,需要每个一个操作都是原子操作。
旋锁是多核操作系统中最常见的CPU互斥机制,是操作系统用于CPU互斥的机制,一般用旋锁来保护全局数据,用户程序不能使用旋锁。
多核操作系统有多个同时执行的单元,多个程序可以同时进行;一个物理CPU都有自己的就绪队列,该就绪队列里面又有许多优先级不同的子队列;一般操作系统会让所有的CPU负载均衡,就是保持所有的CPU忙碌程度均衡;如果发现有些CPU忙,有些CPU闲,就会触发负载均衡,让忙的CPU减少一些task(进程/线程),闲的CPU加上一些task(进程/线程);
CPU消耗型和I/O消耗型
运行的进程如果大部分来进行I/O的请求或者等待的话,这个进程称之为 I/O 消耗型,比如:键盘,这种类型的进程经常处于可以运行的状态,但是都只是运行一点点时间,绝大多数的时间都在处于阻塞(睡眠)的状态。
如果进程的绝大多数都在使用CPU做运算的话,那么这种进程称之为CPU消耗型,比如:做一个大型的运算,没有太多的I/O需求,从系统响应的角度上来讲,调度器不应该经常让他们运行。对于处理器消耗型的进程,调度策略往往是降低他们的执行频率,延长运行时间。
Linux系统为了提升响应的速度,倾向于优先调度I/O消耗型。
Linux进行调度
Linux中有一个总的调度结构,称之为:调度器类(scheduler class)。
Scheduling Class的优先级顺序为: Stop_ask > Real_Time > Fair > Idle_Task,开发者可以根据己的设计需求,來把所属的Task配置到不同的Scheduling Class中,其中的Real_time和Fair是最最常用的。
进程调度器的任务就是合理分配CPU时间及运行的进程:
1、调度器分配的CPU时间不能太长,否则会导致其他的程序响应延迟,难以保证公平性。
2、调度器分配的时间也不能太短,每次调度会导致上下文切换,这种切换开销很大。
注:cgroup的机制:用户可以在程序中调用pthread库自带的线程亲和性设置函数来设置这个线程运行在哪个CPU上。——docker应用的特性之一
进程和线程在多核CPU中的运行关系
操作系统会拆分CPU为一段段时间的运行片,轮流分配给不同的程序,对于多CPU,多个进程可以并行在多个CPU中计算,当然也会存在进程切换;对于单CPU,多个进程在这个单CPU中是并发运行,根据时间片读取上下文+执行程序+保存上下文。同一个进程同一时间段只能在一个CPU中运行,如果进程数小于CPU数,那么未使用的CPU将会空闲。
多线程的概念主要有两种:一种是用户态多线程;一种是内核态多线程,对于内核态多线程(Java1.2之后用内核级线程),在操作系统内核的支持下可以在多核下并行运行;
对于多核CPU,进程中的多线程并行执行。对于单核CPU,多线程在单CPU中并发执行,根据时间片切换线程。同一个线程同一时间段只能在一个CPU内核中运行,如果线程数小于CPU内核数,那么将有多余的内核空闲。
总结一下多核CPU可以同时运行多个进程,但一个进程同一时间只能在一个CPU上执行;物理CPU、逻辑CPU上都存在进程调度,多核CPU可以并行(同时)执行/运行多个线程。
最新评论