QA15 - 21



QA15

为什么用连接器?

  • 链接器可以使得分离编译成为可能:我们可以把一个大的应用程序分解成许多小的,更好管理的模块,单独编译每一个模块。
  • 在修改的时候,只用编译被修改的模块,重新链接就行。能节省大量时间。

连接器工作内容与步骤?

  1. 符号解析
  2. 重定位

局部变量 链接时按照 本地符号 进行解析

全局变量 按照 全局符号 进行解析


链接器对局部变量、参数等符号怎么解析?

  • 对符号的解析:
    • 规则 1:不允许多个同名的强符号
    • 规则 2:若有一个强符号和多个弱符号同名,则选择强符号
    • 规则 3:如果有多个弱符号,选择任意一个

goto L0 的地址符号的强弱?链接时怎么处理?


有哪几种目标文件?怎么查看目标文件的各节信息?

  • 目标文件:
    • 可重定位目标文件:包含数据和代码,编译时多个可重定位目标文件生成可执行目标文件。
    • 可执行目标文件:包含数据和代码,可以被直接加载运行。
    • 共享目标文件:特殊的目标文件,可以在加载或运行时被动态的加载进内存并链接。(这个用于动态链接)
  • 查看目标文件的各节信息
    • objdump

可执行目标文件中的重定位主要完成哪些工作?

  • 将多个单独的代码节(sections)和数据节合并为单个
    节。
  • 将符号从它们在.o文件中的相对位置重新定位到可
    执行文件中的最终绝对内存位置。
  • 用它们的新位置,更新所有对这些符号的引用。

目标文件中的数据节有哪几种,分别有什么区别?

  • ELF头
  • 段头表/程序头表
  • .text节
  • .rodata节(只读数据)
  • .data节(数据/可读写)
  • .bss节(未初始化全局变量)
  • .symtab节(符号表)
  • .rel.text节(可重定位代码)
  • .debug节(调试信息表)
  • 节头表Section header table(每个节的偏移量、大小)

可执行目标文件在执行时由操作系统把各节按大小在内存分配,并拷贝相应内容到内存区



QA16

按照从低到高地址,Linux下内存分成哪几个区?

  • text段(代码段):存放程序代码,通常只读
  • data段(数据段):存储已经初始化的全局变量和静态变量,可读可写。
  • bss段(数据段):存储未初始化的全局变量和静态变量
  • rodate(数据段):存储数据常量,只读。
  • 栈stack(数据段):存储参数变量和局部变量,从高向低地址生长。
  • 堆heap:被动态分配的内存段,从低向高生长。

全局变量怎么实现重定位(32位/64位)?

  • 未解答

子程序怎么实现重定位?

  • 未解答

Linux下归档器/库管理程序是什么?

  • Idconfig(不确定)

库管理中每个函数可以生成单独.o也可以多个函数用一个.o,对应的源程序也是这样的。


静态连接时的目标文件生成与库文件的顺序无关。


共享库的动态连接有哪几种方法?

  • 加载时链接:当可执行文件首次加载和运行时进行动态链接
  • 运行时链接:在程序开始运行后(通过编程指令)进行动态链接

库打桩的应用有哪几个方面?

  • 安全
    • 监禁confinement (沙箱sandboxing)
    • 幕后加密
  • 调试
  • 监控和性能分析
    • 计算函数调用的次数
    • 刻画函数的调用位置(sites)和参数
    • Malloc 跟踪
      • 检测内存泄露
      • 生成地址痕迹(traces)

在什么时候进行库打桩?

  • 打桩可出现在:
    • 编译时:源代码被编译时
    • 链接时间:当可重定位目标文件被静态链接来形成一个可执行目标文件时
    • 加载/运行时:当一个可执行目标文件被加载到内存中, 动态链接,然后执行时


QA17

从哪几方面优化程序?在底层与核心技术方面、上层与应用方面、算法与UI方面等优化重点有何区别?

  • 多个层次进行优化:
    • 算法
    • 数据表示
    • 过程
    • 循环
  • 区别:
    • 不知道

程序的性能优化从哪几方面解决?优化性能为何一定要理解“系统”?

  • 程序是怎样被编译和执行的
  • 现代处理器+存储系统是怎么运作的
  • 怎样测量程序性能,确定“瓶颈”
  • 如何在不破坏代码模块性和通用性的前提下提高性能

编译器能做的程序员也通常采用的一般有用的优化有哪几种?

  • 代码移动
    • 减少计算执行的频率
  • 复杂运算简化
    • 用更简单的方法替换昂贵的操作
    • 移位、加,替代乘法/除法
    • 识别乘积的顺序
  • 共享公用子表达式
    • 重用表达式的一部分
    • GCC 使用 –O1 选项实现这个优化
  • 去掉不必要的过程调用

妨碍编译器优化的因素有哪些?为什么编译器不能优化呢?

  • 函数调用
    • 函数可能有副作用
    • 对于给定的参数,函数可能返回不同的值
  • 内存别名使用

妨碍编译器优化的函数调用怎么进行补救或处理?

  • 使用inline内联函数
    • 用-O1是GCC这样做,但局限于单个文件之内
  • 自己做代码移动

妨碍编译器优化的内存别名怎么进行补救或处理?

  • 移除内存别名,不需要存储中间结果。

编译器优化的其他方法与策略?

  • 减少函数调用
  • 用临时/局部变量累计结果
  • 避免每个循环的边界检查
  • 使用指令级并行

QA17.5 其他编译相关优化技术

  • 寄存器比内存快
  • 用快的指令
  • 用快的寻址方式
  • 位操作比算术运算快
  • 整数比浮点运算块
  • 宏比函数快
  • 简单的结构比复杂结构快
  • 算法很重要
  • C嵌入汇编快
  • 并行比串行快


QA18

简述现代超标量CPU的结构与执行程序特点

  • 一个周期执行多条指令。
  • 这些指令是从一个连续的指令流获取的,通常被动态调度的。

什么容量、延迟界限、发射时间,他们之间有什么关系?

  • 容量:表示能够执行该运算的功能单元的数量

  • 发射时间:表示两个连续的同类型的运算之间需要的最小时钟周期数

  • 延迟界限:简单理解就是延迟,整数加法的延迟界限为1,整数乘法的为3,浮点加法为3,浮点乘法为5

  • 关系:

    • 同一组指令,运算单元容量越大,发射时间越短,延迟界限越短
    • 单元容量一定,延迟界限越大,发射时间越长。

x = (x OP d[i]) OP d[i+1] 与x = x OP (d[i] OP d[i+1])哪一个并行性好?

  • x = x OP (d[i] OP d[i+1]) 的并行性更好
  • 下一个循环的操作可以早一些开始,对之前的数据没有依赖。

采用x0 = x0 OP d[i]; x1 = x1 OP d[i+1]; 的分离累加器方法与x = x OP (d[i] OP d[i+1])的在流水线利用方面有何区别?

  • 第一种情况为两条独立的流水,第二种情况的运算全部在同一条流水线中进行。

什么是SIMD?为什么会提高整数运算的速度?

  • SIMD全称Single Instruction Multiple Data,单指令多数据流,能够复制多个操作数,并把它们打包在大型寄存器的一组指令集。
  • 以同步方式,在同一时间内执行同一条指令。(百度答案我感觉不太对)

对CPU分支预测怎么处理的?程序员与编译器怎么应对?

  • 对分支预测的处理:
    • 静态预测:
      • 预测分支永远不会发生(或永远会发生),因此总是顺序取下一条指令推测执行。仅当条件跳转指令被求值确实发生了跳转,则非顺序的代码地址被加载执行。
    • 动态预测
  • 避免不可预测的分支


QA19

以指令执行为例,说明CPU、内存、外存在数据访问与处理上的区别。

内存MM除了存储单元外,还有哪些硬件?

内存中的行缓冲器通常采用SRAM还是DRAM?

  • DRAM(百度没有答案,谷歌上的一本书说是RDRAM,RDRAM是一种SDRAM)

SRAM与DRAM物理构成有何区别?

  • SRAM存储1位需要4或6个晶体管(双稳态触发器),DRAM需要一个1个电容和1个晶体管(电容的电荷)。

DRAM芯片访问时地址信号线是怎么复用的?

  • CPU将地址A放到总线上
  • 总存储器从总线上读地址A,取出字x,然后将x放到总线上
  • CPU从总线上读入字x,并将其放入寄存器%rax
  • CPu将地址A放到总线上,主存储器读地址A并等待数据到来

内存是4G的,此地址空间不包括BIOS的ROM存储器


内存提高访问速度的方法有哪几种?


为什么每出现新一代DRAM芯片,容量至少提高4倍?

  • 行地址和列地址分时复用, 每出现新一代存储器芯片,至少要增加一根地址线。每加一根地址线,则行地址和列地址各增加一位,所以行数和列数各增加一倍,因而容量至少提高到4倍。

操作系统对硬盘访问采用逻辑方式(簇),由谁来实现此块号与物理磁面号/道号/扇区号的访问呢?

  • 由磁盘控制器维护。

内存与硬盘间传输的块方式采用什么硬件实现?

  • DMA


QA20

存储访问局部性原理是什么意思?

  • 程序倾向于使用距离最近用过的指令/数据地址相近或相等的指令/数据。

Cache访问不命中的种类?

  • 冷不命中(强制不命中):当缓存为空时,对任何数据的请求都会不命中

  • 冲突不命中:当缓存足够大,但是被引用的对象都映射到同一缓存块中,此种不命中称为冲突不命中

  • 容量不命中:当工作集(working set)的大小超过缓存的大小时,会发生容量不命中


Cache怎么组织,其大小怎么计算?

  • Cache共有S(2* s)组,每个组有E(2*
    e)行,每行有1个有效位,t个标记为,有B(2**b)字节
  • cache大小:C = S * E * B数据字节

程序怎么利用高速缓存访问存储器?

  • 程序会先到高速缓存中寻找所需数据。如果能够找到,直接从高速缓存中调用,不再访问内存。当cache中对应位置为空时,发生冷不命中,将从下一级存储中寻找数据并将其放入本级存储。当对应位置不为空但标记位不同是,发生冲突不命中,将从下一级存储中寻找数据并替换此处数据。

空间局部性好的程序也常会发生Cache抖动,导致性能大降,是怎么回事?怎么解决?

  • 可能是因为cache的容量小或每组内的行数较少,关联度低,导致冲突不命中的数量增多。(不确定)

为什么用中间位不用高位作为组/索引?

  • 如果用高位做索引,连续的存储器块会映射到相同的高速缓存块中,具有良好空间局部性的程序顺序扫描一个数组的元素时,高速缓存总保存着一个块大小的数组原内容,高速缓存使用的效率很低。
  • 用中间为作为组索引,相邻的块总是映射到不同的高速缓存行,提高高速缓存的效率。

你的计算机CPU各级Cache多大?是哪一种?C、S、E、B各是多少?


LRU的算法实现?命中行Counter=0,其他行的加1,淘汰计数器最大的-请设计控制逻辑(8路)。

  • 算法实现:

I7的CPU,L2Cache为8路的2M容量,则其B= S= E=

  • 8路:8路组相连,每组有8行,E = 8
  • I7:每块64字节,B = 64
  • 总容量2M,S= 2**20 / 64 / 8 = 2 ** 11 = 2048

全相联Cache有冲突不命中吗?为什么

  • 全相连Cache没有冲突不命中,只有容量不命中
  • 下一级存储器中的数据可对应本级cache中的任意一行,当本级cache未装满时,数据将被装入空白的行,而不会选择替换别的行。

访问高速缓存的地址比内存的地址要短,是吗?

  • 是的
  • 以I7为例,高速缓存地址为6(块索引)+6(组索引)+35(tag)= 47位,内存地址为64位。

QA21

Cache的写命中策略有哪些?

  • 直写(write-through):当cache写命中时,处理器对Cache写入的同时,将数据写入到内存中,内存的数据和Cache中的数据都是同步的。(立即写入存储器)
  • 写回(write-back):当CPU对cache写命中时,只修改cache的内容不立即写入主存,只当此行被换出时才写回主存。(需要一个修改位(脏位),与内存不同时为1,表示被修改)

Cache的写不命中策略有哪些?

  • 写分配(Write Allocate):将主存装入 Cache 中,然后更新相应单元。(好处是更多的写遵循局部性)
  • 非写分配(Not Write Allocate):直接写到主存中,不加载到缓存中。

为什么高速缓存用不命中率而不是命中率来衡量性能?

  • 命中率相差较少时,实际性能相差很多。
  • 命中率为97%和99%的性能可相差两倍。

怎么编写高速缓存友好的代码?

  1. 加快经常性事件:专注在核心函数和内循环上

  2. 使用内层循环的缓存不命中数量降到最低

    • 反复引用变量更好(时间局部性)
    • 步长为1的数据引用模式更好(空间局部性)
  • 关键思想:程序的局部性的这个定性概念通过对缓冲存储器的理解而量化了

重新排列以提升程序的_____局部性

  • 重新排列以提升程序的 空间 局部性

使用分块以提升程序的_____局部性

  • 使用块来提高 时间 局部性

使用分块提高缓冲器命中率的基本思想与算法

  • 充分利用数据的时间局部性。

新的计算机cache技术:指令Cache->微指令Cache、追踪缓存TraceCache等, TLB等

  • 指令Cache->微指令Cache
  • 追踪缓存TraceCache:
    • 一般一级缓存中的指令缓存都是即时解码:而追踪缓存无须每次都进行解码指令,直接做解码,这些指令称为微指令(micro-ops),12K容量能存储12000个微指令。相比可以有效地增加在高速时脉下对指令的解码能力。
  • TLB:
    • 转译后备缓冲器,也被翻译为页表缓存、转址旁路缓存,为CPU的一种缓存,由存储器管理单元用于改进虚拟地址到物理地址的转译速度。当前所有的桌面型及服务器型处理器(如 x86)皆使用TLB。TLB具有固定数目的空间槽,用于存放将虚拟地址映射至物理地址的标签页表条目。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值