操作系统基本原理

  • CPU的三大组件:

    • 运算器:主要用于算术运算和逻辑运算;
    • 控制器:主要用于控制指令的存取过程的;
    • 寄存器:数据暂存较短的时间,但是这个结构比RAM更加复杂,允许数据较长时间的存储在寄存器中;
    • RAM的数据是按照一定的地址进行编址排列的,所以CPU需要具备一定的按照地址进行编址和寻址的能力;
    • North Bridge负责建立CPURAM之间的联系;
    • CPU的总线采用的是复用的方式;
  • PAE:

    • Physical Address Extension:表示物理地址扩展,添加了4 bit最多可以用于寻址2^36个寻址空间,操作系统内核需要支持PAE技术,用于实现32位的机器可以使用64G的地址空间,如果CPU只支持32 bit的体系结构,那么这个技术可以扩展性能,但是即使完成了PAE扩展,单个进程使用内存地址空间任然不能够超过3G,例如Mysql就是单进程多线程模型,32 bit系统上面最多支持2.7G内存;
  • 缓存的原理:

    • 缓存来源于程序数据的局部性,缓存器需要比原始数据存储设备快,但是需要比原始数据存储设备小; 将存储设备热区中的数据保存在缓存设备中,用于弥补存取设备之间的速度差异;缓存设备需要按照一定的置换策略来完成数据热区的交换;常见的置换算法需要自行了解;
    • 程序的局部性表现为:
      • 空间局部性:如果一个数据被访问到,那么控件上面离他很近的数据,也会很快被访问到,大多数缓存算法在加载某个数据时,也会加载其附近的数据,用于提高缓存的命中率;
      • 时间局部性:数据已经被访问一次,那么很短的时间内,存在较大的可能在被访问一次;
  • 缓存设备通常具有多级缓存:
    这里写图片描述

    • 一级缓存:分为一级数据缓存,一级指令缓存,一级缓存通常是每个CPU独有的,如果是多核CPU,那么就存在多个分开的一级缓存,通常设计在CPU的内部;通常为KB单位;
    • 二级缓存:不进行数据和指令的区分,二级缓存通常也是每个CPU独有的’,通常为M;
    • 三级缓存:通常是各个CPU所共享的;
    • 通常来说RAM技术通过按照一定的频率进行刷写,来保证数据在被读取之后仍然是存在的;但是SRAM技术是不需要按照进行刷写的,电路级别的设计要复杂;
  • 缓存的两种技术:

    • 直接映射技术:表示RAM中的任何一段地址的数据都可以存储在缓存设备中的任何一段地址;缺点是如果单次缓存未命中,就需要执行置换策略,在这种情况下,缓存的命中效率依然低下;
      这里写图片描述
    • N路关联技术:缓存中是一个个单独的存储槽,需要记录缓存标记[用于记录缓存是否命中],缓存的索引,缓存的键值;
      这里写图片描述
      • 1路关联技术:表示的是,内存区域中的某个段的某个热区的数据,都可以缓存在同一个区域,如果第一次没有命中,就需要执行缓存策略;
        这里写图片描述
      • 2路关联:表示RAM中的数据可以存储在两个缓存槽中;
      • 8路关联又成为完全关联;
  • 内存更新文件的策略:

    • Write Through:表示的含义CPU如果更新了一级缓存的数据,接下来逐级去更新二级缓存,三级缓存以及内存中的数据,这样导致的结果是效率低下,但是数据的安全性可以得到保证;
    • Write Back:如果CPU更新了一级缓存里面的数据,不会立即更新二级缓存中的数据,而是当这个数据需要被丢弃时,才回去更新这个数据,直至更新到RAM中,这种情况假设CPU不会被立即断电,数据存在不安全的可能性;
    • 现在大多数支持的是Write Back策略,尽可能的保证性能;
  • 桥接芯片就是用来汇总外部的IO芯片,最终完成和CPU的交互;

  • 固态硬盘是接在北桥芯片上面PCI-E的支持并行读写的U盘, 对于连接在南北桥芯片上面的各个设备,是通过IO Port来进行区分的,任何一个硬件设备在连接进入系统时都需要申请一批连续的IO端口号,通常还需要常见设备的控制器来完成对于总线发送的数据进行校验,翻译等功能,驱动通常是驱动设备控制器工作的;

  • PCI槽的作用就是用来扩展计算机的某些功能,为了给某些特殊的设备提供预留的空间,这些预留空间需要保留一定的IO端口;

  • 内核中的两种机制:

    • poll:就是轮询的机制,在一定的时间间隔,主动的询问IO或者特定的事件是否发生;
    • epoll:硬件设备发生特殊的事件,或者CPU要求的IO已经完成,可以通过主动通知的方式来完成;
    • 中断控制器:各个硬件设备在发起中断通知之前,必须先注册中断向量,用于区分不同的硬件设备的中断信号,这些中断控制器是可编程的,又称为可编程中断控制器;
  • 任何可能发生资源竞争的地方,都成为临界区;

  • DMA:表示直接内存访问,如果硬件支持DMA机制,那么内存[通常是16M,相邻的1M空间是BIOS使用的]划分出一段地址空间交给DMA芯片使用,DMA芯片在操作IO,直到IO就绪后,向CPU发起中断请求,通知IO已经完成,

  • CPU提供指令寄存器,用于保存下一条指令的位置,用于在进程切换回来,能够继续执行指令;

  • 内存

  • 内存是按照空间机制进行划分的,通常是按照4K的大划分成为一个个存储槽,称之为page frame,在数据需要进行存储的时候,通常是通过页目录来建立线性地址和逻辑地址之间的物理关系的,并且可以提供内存保护的功能;

  • X86 CPU的设计就不是用来运行虚拟机的,而是在支持了硬件虚拟化之后,支持了虚拟机的特性;

  • CPU指令的环

  • CPU的环通常表示的是CPU指令的运行级别;

    • Ring 0:特权指令模式,也就是内核模式;
    • Ring 1:Linux保留没有使用;
    • Ring 2:Linux保留没有使用;
    • Ring 3:用户控件的指令,只能够运行在Ring 3模式底下;
  • 通常来说为了方便虚拟机的的CPU能够运行在Ring 0上面,需要再次完成一个抽象,讲核心指令运行在Ring -1[硬件虚拟化]上面,保留Ring 0级别的一些非关键指令,让虚拟机的CPU直接运行在Ring 0上面,可以大幅度提升虚拟机的性能;

  • 操作系统架构图
    这里写图片描述

  • Linux中进程是通过双向链表结构
    这里写图片描述

  • 进程的管理依赖于Task_structure来进行管理,又称为进程描述符;销毁进程需要删除进程描述符表,内核就无法完成对于进程的追踪;

  • 进程描述符的结构
    这里写图片描述

  • mm:表示进程映射内存的信息;

  • 进程切换的信息
    这里写图片描述

  • 进程切换又称为上下文切换,假设进程A切换为进程B:

    • 首先A的进程描述符被挂起;
      • stack pointer, other register, EIP register都需要被保存,写入进程的进程描述符中,这个成为保存现场的过程,这个过程是由内核维持的,对于进程描述符的大小都是类似的;
    • B进程的回复现场的过程:
      • stack pointer,other register,EIP register都需要重新读入,并且完成现场的恢复过程;
        *上下文 切换是内核完成的,每一次切换都存在内核的切换上下文切换是必须的,但是需要使用较好的算法来尽量减少上下文切换;
  • Linux允许进程抢占,进程存在优先级,但是不是随时都可以抢占的,必须在Ready状态来进行抢占;每一次tick就可以产生一次抢占;

  • 进程类别:

    • 交互式进程:IO要求非常少,通常是等待进程;
    • 批处理进程:CPU密集型进程,通常需要大量的CPU时间来完成进程数据的处理;
    • 实时进程:优先级最高的;
  • PC:交互式进程的优先级高;

  • 服务器:批处理进程优先级高;

  • 通常的策略是:

    • CPU密集型:时间片长,但是优先级低;
    • IO:通常是时间片长,优先级高;
  • **Linux进程优先级的概念 **

  • 实时优先级:通常和内核级别相关,1-->99,数值越小,优先级越低;

  • 静态优先级:100-->139,通常是数值越小,优先级越高;

  • 实时优先级比静态优先级高;
    这里写图片描述

  • 上面的RT表示的含义是实时优先级否则就是静态优先级,20表示含义不是优先级为20而是用户空间的进程ID120,默认启动的进程的NICE值为0,对应的进程优先级是120,

  • 查看实时优先级,Nice
    这里写图片描述

  • 上面显示信息的含义:

    • [cmd]:表示是一个内核线程;
    • 对于RT priority99的,表示只要是这个线程或者级才能启动,就应该立即得到运行;
    • 对于上图,有些内核级别的线程的不具有RT Prioty,仅仅具有静态优先级别;
    • 对于第一列显示的是对于进程的调度器类型TS:表示SCHED_OTHER;FF:表示FIFO;
  • Linux内核对于进程的调度类别

  • 实时进程:

    • SCHED_FIFO:表示先进先出队列,调度策略粗糙;
    • SCHED_RR:表示轮询调度级别;
  • 100-->139

    • SCHED_Other:是专门用来调度用户空间进程的100--->139;
    • SCHED_BATCH:
    • SCHED_IDLE:
  • Rhel6.4以后已经不使用tick机制,也就是无tick系统,进程之间的通过中断系统来进行交互,

  • 动态优先级:

    • 为了防止某些优先级较低的进程长时间得到CPU资源,内核会临时的调整这些进程的优先级,让进程得到CPU资源;,主要是针对于100-->139的这些进程,并且监控这些进程是否长时间没有得到CPU资源;当然也存在调低优先级的情况;
    • 动态优先级:dynamicpriority = max(100,min(static priority - bonus[奖惩值] + 5, 139));对于bonus的范围最多是0--->10之间;
  • 手动调整优先级:

    • 100--->139:
      • Nice:Nice N COMMAND:表示使用N作为其优先级;
      • renice -n # PID:表示手动调整其优先级,;
    • chrt:
      • -f -p [prio] PID:set policy to SCHED_FIFO;
      • -r -p [prio] PID:set policy to SCHED_RR (default) ;
  • Linux 2.6以后的内核对于进程按照优先级划分为99-->1,以及100--->139一共是139*2个队列,每一种类的优先级包括活动队列以及 过期队列,过期队列,里面是分配了CPU时长,但是仍然需要多于的时间片的进程;这两个队列并不是固定的,当A1[活动队列]为空,A1变成非活动队列,A2变成活动队列;

  • 通过上述算法保证进程调度的o(1)调度,调度算法是CFQ:Complete Fair Queue,主要是用来调度SCHED_Other,尽可能保证公平,这种算法不适合于服务器,而是适合于桌面系统;

  • 进程的地址空间
    这里写图片描述

  • Text:表示只读段,通常是代码的指令区域;

  • data:进行了初始化的数据区域;

  • BSS:表示初始化为0的变量;

  • Heap:表示堆,包括打开的文件;

  • stack:表示栈,本地变量,函数的参数,函数的返回地址等;

  • Linux的第一个进程是Init,所有的子进程的父进程最终都是Init,进程创建使用Fork()系统调用来完成,在一开始,子进程和父进程共享所有的地址空间,在子进程需要完成Copy On Write时,子进程就存在自己的地址空间;

  • CPU完成对于内存的访问,至少需要三个时钟周期:

    • 第一个周期向内存控制器传输寻址要求,内存控制器取得对应的内存的地址;
    • 第二个时钟周期,请求内存控制器返回的地址,并且施加一定的内存地址控制机制,一般来说是锁机制;
    • 第三个是周期完成对于内存地址空间的读或者写操作,SMP的处理机制,对于关键资源的竞争是导致性能瓶颈的重要原因,在一定的范围内,性能是上升的,但是之后性能会下降;
      这里写图片描述
  • 对于关键资源的征用可以通过设置每个CPU专用的内存控制器来解决, 但是由于内存是共享的,可能 CPU 0使用的资源在CPU 1的内存控制器可访问的地址空间中;
    这里写图片描述

  • 对于每个CPU都存在自己的内存控制器,并且在一定情况下,允许访问其他CPU的内存控制器的处理器架构,称为NUMA,也就是非一致性内存访问,在这种机制下,每一个CPU都存在自己的内存以及内存控制器,通常来说内存控制器是集成在CPU里面的,但是这些内存控制器以及内存区域是弱共享的,如果要去访问其他CPU,需要跨越总线来访问,性能会下降;

  • 在上面这种架构下,为了保证性能,应该尽量访问自己内存控制器,但是内核需要对于进程进行Re balance,这种机制是导致访问其他内存控制器的主要原因;

  • 对于上面的这种机制需要使用CPU绑定的功能来完成CPU affinity

  • 首先需要下载几个软件包:

root@westos:~#  apt-get install numad -y
root@westos:~#  apt-cache search numactl
  • 查看提供的命令:
    这里写图片描述

  • 查看
    这里写图片描述

    • node0:如果存在多个Node,后面会继续显示;
    • numa_mit:表示在当前内存控制器上面命中的次数;
    • numa_miss:表示在当前内存控制器上面没有命中的次数;
    • numa_foreign:表示分配给CPU 0的内存再被CPU 1或者其他的CPU使用;
  • -p PID :用于查看某一个特定进程的内存分配的;
    这里写图片描述

  • -s:用于显示哪一个node或者是那些node的内存命中情况的,由于这个处理器不是NUMA架构的,所以只能够查看一个node;
    这里写图片描述

  • numactl:用于控制CPU共享内存的策略的;

  • --cpunodebind=nodes, -N nodes:Only execute command on the CPUs of nodes. Note that nodes may consist of multiple CPUs. nodes may be specified as noted above.用于实现CPU和某个COMMAND的绑定;

  • --physcpubind=cpus, -C cpus:用于实现进程和CPU的绑定;

  • --show:
    这里写图片描述

  • numad:对于上面的命令需要根据自己的观察,手动的绑定某个进程到某个CPU上面,这个命令是用于自动的绑定某个进程到某个CPU或者是节点上面,这个命令可以大幅度的系统性能

  • 上面是通过命令的方式将CPU Nodeprocess进行绑定;

  • 上面的命令是对于NUMA架构的来实现绑定的,如果对于非NUMA架构的可以使用命令taskset;

  • taskset:用于将某个进程绑定在某个CPU上面;

    • 使用mask的方式来引用CPU,通常是:0x0000 0001表示第0CPU;
    • 0x 0101:表示第0号和第2CPU;
  • 例如绑定第二号CPU110进程taskset -p 0x0000 0004 110;
    这里写图片描述

  • 简单的表示:taskset -p -c 3 101:表示绑定第三号CPU101进程上面;
    这里写图片描述

  • 对于上面绑定了进程的CPU仍然是可能发生进程调度的,可以通过想内核传递参数,来隔离CPU,不再允许进程切换到这个CPU上面,需要传递参数isolcpus=cpu number,cpu number,执行了上述操作的CPU仍然需要服务于中断,所以需要将中断绑定在那些非隔离的CPU上面,从而避免那些非隔离的CPU处理中断;

  • 中断绑定的方法:

root@westos:~# echo 'CPU MASK' > /proc/irq/0/smp_affinity
  • 需要进行进程绑定是因为某个繁忙的进程经常被切换出去,或者上下文切换很频繁,尤其需要考虑TASK_RUNNABLE以及TASK_UNINTERRUPTABLE状态的进程;

  • 查看CPU活动状况的命令

  • sar -q:可能需要安装sysstat这个软件包,这个命令相当强大;
    这里写图片描述
    这里写图片描述

  • sar -P 0 1:用于显示某个CPU的使用情况
    这里写图片描述

  • top:
    这里写图片描述

  • w:

  • uptime:Tell how long the system has been running
    这里写图片描述

  • vmstat:
    这里写图片描述

  • 模拟使用SAR来测试HTTPD服务器的压力测试
    这里写图片描述
    这里写图片描述

  • mpstat:用于显示多个CPU的使用状况的;

    • -P:用于显示指定的某个CPU的,否则显示所有的
      这里写图片描述
    • I CPU #:用于显示某个CPU对于中断的处理情况

这里写图片描述

  • iostat:用来报告CPU以及输入输出设备的统计数据的
    这里写图片描述
  • 还可以直接通过查看/proc/stat来查看CPU的状况,其实上面的命令都是从这个文件读取的信息,并通过可读的方式来进行显示的
    这里写图片描述
  • dstat:这个命令同样是异常强大
    这里写图片描述
    这里写图片描述
    这里写图片描述
  • 查看上下文切换的次数
  • vmstat显示的内容的cs表示的就是上下文切换的次数
    这里写图片描述

这里写图片描述

  • 这个deepin的上下文切换次数有点高的可怕;
  • CPU的调度域:
  • CPU组织成倒置的文件系统,所有的CPU域都是根域的一部分;运行在根域上面表示运行在所有的CPU上面;
  • 创建CPU域的过程:
root@westos:~# mkdir /cpusets
root@westos:~# vim /etc/fstab 
cpuset          /cpusets         cpuset defaults  0   0
root@westos:~# ls /cpusets/
cgroup.clone_children  cpuset.mem_exclusive            cpuset.mems
cgroup.procs           cpuset.mem_hardwall             cpuset.sched_load_balance
cgroup.sane_behavior   cpuset.memory_migrate           cpuset.sched_relax_domain_level
cpuset.cpu_exclusive   cpuset.memory_pressure          notify_on_release
cpuset.cpus            cpuset.memory_pressure_enabled  release_agent
cpuset.effective_cpus  cpuset.memory_spread_page       tasks
cpuset.effective_mems  cpuset.memory_spread_slab
  • 一共是4CPU
    这里写图片描述
  • CPU的架构不是NUMA架构,所以内存都是属于根域的
    这里写图片描述
  • 表示运行的进程ID
    这里写图片描述
  • 创建一个目录,会自动创建一些必要的文件
    这里写图片描述
  • 这里面的文件是没有多少内容的,可以进行绑定
root@westos:~# echo 0 > /cpusets/domain1/cpuset.cpus 
root@westos:~# echo 0 > /cpusets/domain1/cpuset.mems 
root@westos:~# echo 11261[这个进程号必须是存在的] > /cpusets/domain1/tasks 
  • 验证绑定的效果
    这里写图片描述
  • 11261运行在0CPU上面,如果进行测试,那么也是不会改变
    这里写图片描述
  • 通过命令的方式将某个进程绑定在CPU上面
    这里写图片描述
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值