什么是缓存(Cache)?为什么需要缓存?如何提高缓存的命中率?缓存是不是最快的?

  • Cache即CPU的高速缓冲存储器,是一种是用于减少处理器访问内存所需平均时间的部件;
  • 由于CPU的计算速度远远大于从CPU向内存取数据的速度,如果每次都让CPU去内存取数据,会导致CPU计算能力的浪费,所以人们设计了缓存,CPU通过读写缓存来获取操作数,结果也通过缓存写入内存;
  • 注意程序的局部性原理,在遍历数组时按照内存顺序访问;充分利用CPU分支预测功能,将预测的指令放到缓存中执行;此外缓存的容量和块长是影响缓存效率的重要因素。
  • 缓存不是最快的,寄存器更快。
  • Cache 的基本原理

编译器、汇编器和链接器的基本概念

编译器

  • 编译器把高级语言翻译为机器语言
  • 得到 hello.s 文件,这个是汇编语言程序
  • 不同的高级语言翻译的汇编语言相同

汇编器

  • 汇编器将 hello.s 翻译成机器语言指令,把这些指令打包成可重定位目标程序。
  • 得到 .o 文件,是一个二进制文件,它的字节码是机器语言指令,不再是字符。前面两个阶段都还有字符。

链接器

  • 链接器负责 .o 文件的合并。得到的是可执行目标文件。
  • gcc会到系统默认的搜索路径 /usr/lib下进行查找,也就是链接到 libc.so.6 库函数中去。 函数库一般分为静态库和动态库两种。
  • 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为 .a
  • 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为 .so,如前面所述的 libc.so.6 就是动态库。gcc在编译时默认使用动态库。

编译过程的五个阶段

  • 第一阶段:词法分析
    1. 词法分析的任务是:输入源程序,对构成源程序的字符串进行扫描和分解,识别出一个个的单词(亦称单词符号或简称符号)。如基本字(begin、end、if、for、while),标识符、常数、运算符和界符(标点符号、左右括号)。
    2. 在词法分析阶段的工作中所依循的是语言的词法规则(或称构词规则)。描述词法规则的有效工具是正规式和有效自动机。
  • 第二阶段:语法分析
    1. 语法分析的任务是:在词法分析的基础上,根据语言的语法规则,把单词符号串分解成各类语法单位(语法范畴)。如“短语”、“句子”、“程序段”和“程序”等。
    2. 通过语法分析,确定整个输入串是否构成语法上正确的“程序”。语法分析所依循的是语言的语法规则。
    3. 词法分析是一种线性分析,而语法分析是一种层次结构分析。例如:Z = X + 0.618 · Y;代表一个“赋值语句”,而其中的X + 0.618 · Y 代表一个“算术表达式”。因而,语法分析的任务就是识别X + 0.618 · Y为算术表达式。同时,上述整个符号串乘以十属于赋值语句这个范畴。
  • 第三阶段:词义分析与中间代码产生
    1. 这一阶段的任务是:对语法分析所识别出的各类语法范畴,分析其含义,并进行初步翻译(产生中间代码)
    2. 这一阶段通常包含两个方面的工作。首先,对每种语法范畴进行语义i安插,例如,变量是否定义、类型是否正确等等。如果语义正确,则进行另一方面工作,即进行中间代码的解释。
  • 第四阶段:优化
    1. 优化的任务是:对前段产生的中间代码进行加工变换,以便在最后阶段能产生出更为高效(省时间和空间)的目标代码
    2. 优化的主要方面有:公关子表达式的提取、循环优化、删除无用代码等等。有时,为了便于“并行运算”,还可以对代码进行并行化处理。
    3. 优化所依循的原则是程序的等价变换规则。
  • 第五阶段:目标代码生成
    1. 这一阶段的任务是:把中间代码(或经优化处理之后)变换成特定机器上的低级语言代码
    2. 这阶段实现了最后的翻译,它的工作有赖于硬件系统结构和机器指令含义。
    3. 这阶段工作非常复杂,设计到硬件系统功能部件的运用,机器指令的选择,各种数据类型变量的存储空间分配,以及寄存器和后援寄存器的调度,等等。
    4. 目标代码的形式可以是绝对指令代码或可重定位的指令代码或汇编指令代码。如目标代码是绝对指令代码,则这种目标代码可立即执行。如果目标代码是汇编指令代码,则需汇编器汇编之后才行运行。
    5. 必须指出,现在多数实用编译程序所产生的目标代码都是一种可重定位的指令代码。这种目标代码在运行前必须借助于一个连接装配程序把各个目标模块(包括系统提供的库函数)连接在一起,确定程序变量(或常数)在主存中的位置,装入内存中指定的起始地址,使之成为一个可以运行的绝对指令代码程序。

CPU由什么构成的

  • CPU内部主要由 运算器控制器寄存器 三大部分组成。
    1. 运算器:负责算术运算(+ - * / 基本运算和附加运算)和逻辑运算(包括 移位、逻辑测试或比较两个值等)。
    2. 控制器 负责应对所有的信息情况,调度运算器把计算做好。
    3. 寄存器 它们可用来暂存指令、数据和地址。既要对接控制器的命令,传达命令给运算器;还要帮运算器记录处理完或者将要处理的数据。

原码、反码、补码

  1. 正数的补码保持原码不变(反码也是):3 = { 0_0000011 }
  2. 负数的补码先求反码,然后再加 1 :-5 = [ 1_1111010 ] + 1 = { 1_1111011 }
  • 于是 3 + { -5 } = { -2 } 的计算过程为:
  • { 0_0000011 } + { 1_1111011 } = { 11111110 }
  • 至此,通过补码就成功解决了数字 0 在计算机中非唯一编码的问题,且也能实现减法变加法。

寄存器有哪几种类型(主要)

  • 数据寄存器
  • 指令寄存器
  • 程序寄存器
  • 地址寄存器
  • 累加寄存器
  • 程序状态字寄存器