zoukankan      html  css  js  c++  java
  • 深入理解计算机系统读书笔记一

    基础知识

    为什么计算机需要高速缓存?

    计算机程序是存储在磁盘中的。程序运行时,需要将程序加载到主存(内存条)中,但处理器处理程序时,又需要将指令从主存复制到处理器。程序的复制是开销。需要使用一种方式来使复制操作尽可能快的执行。根据机械原理,存储能力较大的设备的读写速度较慢。为了解决主存与处理器之间存在的读取数据的差距,就使用一种更小更快的存储设备,称为高数缓存存储器(cache memory)作为暂时集结的地方。
    eaYWxx.png

    eat9oQ.md.png

    操作系统的两个基本功能

    1.防止硬件杯失控的应用程序滥用
    2.向应用程序提供简单一致的机制来控制复制而又通常不大相同的低级硬件设备。操作系统通过几个基本的抽象概念(进程、虚拟内存和文件)来实现这两个功能。

    什么是进程?

    进程是操作系统对一个正在运行的硬件的一种抽象。操作系统会保持跟踪进程运行所需的所有状态信息,这些状态信息被称为上下文信息,器包括PC和寄存器的当前值,以及主存的内容。当操作系统决定要把控制权从当前进程转移道某个新进程时,就会进行上下文切换,即保存当前进程的上下文、恢复新进程的上下文,将控制权转移道新进程。
    从一个进程道另一个进程的转换是由操作系统内核进行管理的。内核是操作系统代码常驻内存的部分。

    什么是线程

    在现代操作系统中,一个进程可以由多个称为线程的执行单元组成。每个线程都运行在进程的上下文中,线程共享进程的代码和全局数据。线程之间更容易进行数据共享,线程也比进程更加的高效。在多处理器环境中,多线程是一种使得程序k

    什么是虚拟内存

    虚拟内存为每个进程提供了一个假象,即每个进程都在独占的使用内存。每个进程看到的内存都是一致的,称为虚拟地址空间。
    ewXldA.png
    每个进程的虚拟地址空间由大量准确定义的区构成,每个区都有专门的功能。从低地址道高地址逐步向上分别是:
    1.程序代码和数据区。代码是从同一固定地址开始的,紧接着是和C全局变量相对应的数据位置。其大小在进程运行时就被指定了大小。
    2.堆。堆可以在运行是动态的扩展和收索。
    3.共享库。在地址空间中的一部分是用来存放共享库代码和数据的区域。
    3.栈。位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数调用。用户栈也可以在程序执行期间动态的拓展和收缩。
    4.内核虚拟内存。地址空间的顶部时为内核保留的。不允许应用程序读写这个区域的内容或直接调用内核代码定义的函数。

    文件

    文件是就是字节序列。磁盘、键盘、显示器、网络都可以看作文件。

    什么是指令集体系结构,它有什么作用?

    一个处理器支撑的指令和指令的字节级编码称为它的指令集体系结构(ISA)。ISA在编译器编写者和处理器设计人员之间提供了一个概念的抽象层,编译器编写者只需要知道允许那些指令,以及它们是如何编码的;而处理器设计者必须建造出执行这些指令的处理器。

    影响编译器对程序进行优化的几个因数

    1.是否存在内存别名的使用

    void twiddle1(long *xp,long *yp)
    {
        *xp += *yp;
        *xp += *yp;
    }
    void twiddle2(long *xp,long *yp)
    {
        *xp+=2* *yp;
    }
    
    /*twiddle1好像和twiddle2的功能好像是一样的,但如果考虑xp和yp指向同一片内存空间(内存别名),那么显然两个函数的功能也就完全不同了,这会严重限制编译器对代码的优化*/
    

    2.函数调用可能有副作用

    long f();
    long func1()
    {
        return f()+f()+f()+f();
    }
    
    long func2()
    {
        return 4*f();
    }
    
    /*
    看似func1和func2计算结果相同。但是如果f()有副作用(比如调用其会对某一全局变量进行修改),这样func1和func2的结果就是不同的了,编译器一般不会试图判断一个函数是否存在副作用,所以编译器一般也不会冒风险进行向上面这样的优化,编译器会假设最糟的情况,保持所有的函数调用不变
    */
    

    流水线优化和分支预测技术

    在传统的单周期处理机中,一条指令必须要等待上一条指令结束才能执行。通过使用流水线优化延伸重叠方式,使指令的解释过程进一步细化,提高各部件的利用率,一调高指令的执行速度。
    e6AJ8P.md.png

    当图中的流水线只不过是一种理想的状态。当遇到分支指令时,因为可能会产生跳转所以处理器无法确定下一条指令。处理器必须等待分支指令处理完毕,才能确定下一条进入流水线的指令,而造成了性能的下降。分支预测技术就是为了解决这个问题的。
    分支预测技术分为编译时进行的静态分支预测和硬件在执行时的动态分支预测。

    静态分支预测技术

    静态分支预测技术是在编译时进行的。一种简单的办法时二选一;更将精确的办法是基于原先的运行结果的统计进行预测。

    动态分支预测技术

    处理器使用投机执行的技术,处理器会开始取出位于他预测的分支会跳转到的地方的指令,并对指令译码,如果过后确定分支预测错误,会将状态设置到分支点的状态,并开始取出和执行另一个分支的指令。
    在指令控制单元中存在一个退役单元,它记录正在进行的处理,并保证它遵守机器机程序的语义顺序。退役单元还控制着寄存器的更新。指令译码时,关于指令的信息都被防止到一个队列中。这个信息会一直保持到队列中,知道发现以下两种结果中的一个:一旦一条指令的操作执行完成了,而且引起这条指令的分支点也都被确认预测正确,那么这条指令就可以退役了,它对寄存器的所有更新都回被实际执行。另一方面,如果引起这条指令的分支点预测错误,那么该指令会被清空,所有计算结果都被丢弃。

    关于分支预测的一个例子https://www.cnblogs.com/yangecnu/p/4196026.html

    访问主存

    数据流通过称为总线的共享电子电路在处理器何让DRAM主存之间来来回回。每次CPU和主存之间的数据传送都是通过一系列步骤来完成的,这些步骤称为总线事务。读事务从主存传送数据到CPU。写事务从CPU传送数据到主存。

    CPU是如何将主存中的内容加载到寄存器的

    movq A,%rax
    

    首先CPU通过总线接口在总线上发起读事务。CPU将地址A放到系统总线上,I/O桥将信号传递到内存总线。主存从内存总线中收到地址信号,并以此在DRAM中取出数据,并及那个数据写到内存总线中。I/O桥将内存总线信号翻译为系统总线信号,然后沿着西戎总线传递。CPU通过系统总线接收数据,并将数据复制到寄存器%rax.

    CPU是如何将寄存器中的值写到主存

    movq %rax,A
    

    CPU发起写事务。CPU将地址放到系统总线上。内存从内存总线读出地址,并等待数据到达。接下来,CPU将%rax中的数据复制到系统总线。最后主存从内存总线独处数据字,并将这些位存储到DRAM中。

  • 相关阅读:
    sql 自定义函数-16进制转10进制
    编写一个单独的Web Service for Delphi
    Web Service
    无需WEB服务器的WEBServices
    Svn总是提示输入账号密码
    阿里云服务器SQLSERVER 2019 远程服务器环境搭建
    svn客户端使用
    数据库设计规则(重新整理)
    数据库表字段命名规范
    怎样去掉DELPHI 10.3.3 启动后的 security alert 提示窗体
  • 原文地址:https://www.cnblogs.com/zofun/p/11443917.html
Copyright © 2011-2022 走看看