元月's blog 元月's blog
首页
  • 基础
  • 并发编程
  • JVM
  • Spring
  • Redis篇
  • Nginx篇
  • Kafka篇
  • Otter篇
  • Shardingsphere篇
  • 设计模式
  • MySQL
  • Oracle
  • 基础
  • 操作系统
  • 网络
  • 数据结构
  • 技术文档
  • Git常用命令
  • GitHub技巧
  • 博客搭建
  • 开发工具
更多

元月

临渊羡鱼,不如退而结网
首页
  • 基础
  • 并发编程
  • JVM
  • Spring
  • Redis篇
  • Nginx篇
  • Kafka篇
  • Otter篇
  • Shardingsphere篇
  • 设计模式
  • MySQL
  • Oracle
  • 基础
  • 操作系统
  • 网络
  • 数据结构
  • 技术文档
  • Git常用命令
  • GitHub技巧
  • 博客搭建
  • 开发工具
更多
  • 基础

  • 数据结构

  • 网络

  • 操作系统

    • Linux常用命令记录
    • 操作系统的整体结构认识
      • 一、冯 诺伊曼 计算机模型
      • 二、CPU
        • 1、CPU内部结构
        • 2、CPU缓存结构
        • 3、CPU运行安全等级
      • 三、内存管理
        • 1、执行空间保护
        • 2、线程模型
        • 3、进程与线程
    • 缓存一致性协议(MESI)
  • 计算机网络
  • 操作系统
元月
2022-08-02
目录

操作系统的整体结构认识

# 操作系统的整体结构认识

# 一、冯 诺伊曼 计算机模型

img

计算机五大核心组成部分

  1. 控制器(Control):是整个计算机的中枢神经,其功能是对程序规定的控制信息进行解释,根据其要求进行控制,调度程序、数据、地址,协调计算机各部分工作及内存与外设的访问等。

  2. 运算器(Datapath):运算器的功能是对数据进行各种算术运算和逻辑运算,即对数据进行加工处理。

  3. 存储器(Memory):存储器的功能是存储程序、数据和各种信号、命令等信息,并在需要时提供这些信息。

  4. 输入(Input system):输入设备是计算机的重要组成部分,输入设备与输出设备合你为外部设备,简称外设,输入设备的作用是将程序、原始数据、文字、字符、控制命令或现场采集的数据等信息输入到计算机。常见的输入设备有键盘、鼠标器、光电输入机、磁带机、磁盘机、光盘机等。

  5. 输出(Output system):输出设备与输入设备同样是计算机的重要组成部分,它把外算机的中间结果或最后结果、机内的各种数据符号及文字或各种控制信号等信息输出出来。微机常用的输出设备有显示终端CRT、打印机、激光印字机、绘图仪及磁带、光盘机等。

# 二、CPU

# 1、CPU内部结构

image-20220802141118098

  • 控制单元

    控制单元是整个CPU的指挥控制中心,由指令寄存器IR(Instruction Register)、指令译码器ID(Instruction Decoder)和 操作控制器OC(Operation Controller) 等组成,对协调整个电脑有序工作极为重要

  • 运算单元

    运算单元是运算器的核心。可以执行算术运算(包括加减乘数等基本运算及其附加运算)和逻辑运算(包括移位、逻辑测试或两个值比较)

  • 存储单元

    存储单元包括 CPU 片内缓存Cache和寄存器组,是 CPU 中暂时存放数据的地方,里面保存着那些等待处理的数据,或已经处理过的数据,CPU 访问寄存器所用的时间要比访问内存的时间短

# 2、CPU缓存结构

现代CPU为了提升执行效率,减少CPU与内存的交互(交互影响CPU效率),一般在CPU上集成了多级缓存架构,常见的为三级缓存结构

  • L1 Cache,分为数据缓存和指令缓存,逻辑核独占
  • L2 Cache,物理核独占,逻辑核共享
  • L3 Cache,所有物理核共享

image-20220802142410459

还有一点值得注意的是:缓存是由最小的存储区块-缓存行(cacheline)组成,缓存行大小通常为64byte。

CPU读取存储器数据过程

1、CPU要取寄存器X的值,只需要一步:直接读取。

2、CPU要取L1 cache的某个值,需要1-3步(或者更多):把cache行锁住,把某个数据拿来,解锁,如果没锁住就慢了。

3、CPU要取L2 cache的某个值,先要到L1 cache里取,L1当中不存在,在L2里,L2开始加锁,加锁以后,把L2里的数据复制到L1,再执行读L1的过程,上面的3步,再解锁。

4、CPU取L3 cache的也是一样,只不过先由L3复制到L2,从L2复制到L1,从L1到CPU。

5、CPU取内存则最复杂:通知内存控制器占用总线带宽,通知内存加锁,发起内存读请求,等待回应,回应数据保存到L3(如果没有就到L2),再从L3/2到L1,再从L1到CPU,之后解除总线锁定。

局部性原理

  • 时间局部性

    如果一个信息项正在被访问,那么在近期它很可能还会被再次访问。比如循环、递归、方法的反复调用等,这些往往被认为调用优先级比较高

  • 空间局部性

    如果一个存储器的位置被引用,那么将来他附近的位置也会被引用。比如顺序执行的代码、连续创建的两个对象、数组等。

    举个空间局部性原则例子,二维数组的横向操作和纵向操作耗时对比:

    public class TwoDimensionalArraySum {
        private static final int RUNS = 100;
        private static final int DIMENSION_1 = 1024 * 1024;
        private static final int DIMENSION_2 = 6;
        private static long[][] longs;
    
        public static void main(String[] args) throws Exception {
            /*
             * 初始化数组
             */
            longs = new long[DIMENSION_1][];
            for (int i = 0; i < DIMENSION_1; i++) {
                longs[i] = new long[DIMENSION_2];
                for (int j = 0; j < DIMENSION_2; j++) {
                    longs[i][j] = 1L;
                }
            }
            System.out.println("Array初始化完毕....");
    
            long sum = 0L;
            long start = System.currentTimeMillis();
            for (int r = 0; r < RUNS; r++) {
                for (int i = 0; i < DIMENSION_1; i++) {//DIMENSION_1=1024*1024
                    for (int j=0;j<DIMENSION_2;j++){//6
                        sum+=longs[i][j];
                    }
                }
            }
            System.out.println("spend time1:"+(System.currentTimeMillis()-start));
            System.out.println("sum1:"+sum);
    
            sum = 0L;
            start = System.currentTimeMillis();
            for (int r = 0; r < RUNS; r++) {
                for (int j=0;j<DIMENSION_2;j++) {//6
                    for (int i = 0; i < DIMENSION_1; i++){//1024*1024
                        sum+=longs[i][j];
                    }
                }
            }
            System.out.println("spend time2:"+(System.currentTimeMillis()-start));
            System.out.println("sum2:"+sum);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

# 3、CPU运行安全等级

CPU有4个运行级别,分别为:

  • ring0

  • ring1

  • ring2

  • ring3

    Linux与Windows只用到了2个级别:ring0、ring3,操作系统内部内部程序指令通常运行在ring0级别,操作系统以外的第三方程序运行在ring3级别,第三方程序如果要调用操作系统内部函数功能,由于运行安全级别不够,必须切换CPU运行状态,从ring3切换到ring0,然后执行系统函数,说到这里相信同学们明白为什么JVM创建线程,线程阻塞唤醒是重型操作了,因为CPU要切换运行状态。

下面我大概梳理一下JVM创建线程CPU的工作过程

step1:CPU从ring3切换ring0创建线程

step2:创建完毕,CPU从ring0切换回ring3

step3:线程执行JVM程序

step4:线程执行完毕,销毁还得切回ring0

# 三、内存管理

# 1、执行空间保护

操作系统有用户空间与内核空间两个概念,目的也是为了做到程序运行安全隔离与稳定

image-20220802150158774

# 2、线程模型

内核线程模型(KLT)

系统内核管理线程(KLT),内核保存线程的状态和上下文信息,线程阻塞不会引起进程阻塞。在多处理器系统上,多线程在多处理器上并行运行。线程的创建、调度和管理由内核完成,效率比ULT要慢,比进程操作快。

image-20220802150313696

用户线程模型(ULT)

用户程序实现,不依赖操作系统核心,应用提供创建、同步、调度和管理线程的函数来控制用户线程。不需要用户态/内核态切换,速度快。内核对ULT无感知,线程阻塞则进程(包括它的所有线程)阻塞。

image-20220802150342344

# 3、进程与线程

什么是进程?

现代操作系统在运行一个程序时,会为其创建一个进程;例如,启动一个Java程序,操作系统就会创建一个Java进程。进程是OS(操作系统)资源分配的最小单位。

什么是线程?

线程是OS(操作系统)调度CPU的最小单元,也叫轻量级进程(Light Weight Process),在一个进程里可以创建多个线程,这些线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量。CPU在这些线程上高速切换,让使用者感觉到这些线程在同时执行,即并发的概念,相似的概念还有并行!

线程上下文切换过程:

image-20220802150603103

Linux常用命令记录
缓存一致性协议(MESI)

← Linux常用命令记录 缓存一致性协议(MESI)→

最近更新
01
otter二次开发-支持按目标端主键索引Load数据
08-03
02
mvnw简介
06-21
03
gor流量复制工具
06-03
更多文章>
Theme by Vdoing | Copyright © 2022-2024 元月 | 粤ICP备2022071877号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式