寄存器分配 影响程序速度的因素 cpu, register, cache, memory, disk

Slides:



Advertisements
Similar presentations
年輕駕駛交通工具 考上駕照的 18 歲, 正好是高中畢業, 離家工作、上大學 的時候。 年輕人對新環境的 好奇及生疏,以及 尚未養成良好駕駛 習慣,造成意外的 產生。
Advertisements

§2 计算机系统结构、组成与实现 计算机系统结构、组成与实现的定义和内涵 计算机系统结构、组成和实现的相互关系.
广州宜家选址分析 0连锁 李若谷 陈玉风 黄小飞 蓝柔盈.
多核结构与程序设计 杨全胜 东南大学成贤学院计算机系.
第八章 组织文化的整合 ——并购中的文化整合(二) 小组成员:浦若蓉、朱谷一、贾彦彦.
第五章 中央处理器 5.1 CPU的组成和功能 5.2 指令周期 5.3 时序产生器和控制方式 5.4 微程序控制器 5.5 微程序设计技术
CHAPTER 9 虛擬記憶體管理 9.2 分頁需求 9.3 寫入時複製 9.4 分頁替換 9.5 欄的配置法則 9.6 輾轉現象
第一章 C语言概述 计算机公共教学部.
Fortran — 世界上推出的第一种高级程序设计语言 谢建勤(电子与信息工程学院)
第一章 计算机基础知识 计算机的发展简史 1 计算机软件系统 6 计算机的定义和分类 2 微型计算机的组成 7 计算机的特点和用途 3
Access数据库程序设计 总复习.
输入输出程序设计 输入输出的基本概念 无条件方式输入输出 查询方式输入输出 中断方式输入输出.
计算机组成原理 北京理工大学计算机科学工程系 赵清杰 北京理工大学计算机科学工程系.
指導老師:楊淑娥 組別:第一組 成員:劉怡萱4a0i0066 吳珮瑜4a0i0070 林秋如4a0i0075 陳婉婷4a0i0076
組員:4A140013張瓊云 4A1I0039石宜芬 4A1I0909許峻綱 指導老師:王立杰老師
程序设计基础知识.
推行使用散装预拌砂浆 全面贯彻落实禁现政策
最新計算機概論 第3章 計算機組織.
護理理論期末報告(99上學期) 指導老師:謝春滿 老師 護理系進修部1-3組 第三組
第10章 DOS功能调用与BIOS中断调用.
程序设计思想与方法入门篇 庄天红.
第四章 存储体系.
数字系统设计及VHDL实践 专题五 专用集成电路 设计中的并行算法 主 讲 人:徐向民 单 位:电子信息学院.
大连理工大学软件学院 软件工程系 赖晓晨 计算机组成与结构 大连理工大学软件学院 软件工程系 赖晓晨
指導老師:陳韻如 班級:幼保二甲 姓名:林靜宜 學號:4A0I0033
第一章 引论 1.1操作系统的概念 计算机系统: 计算机硬件 计算机软件 计算机硬件:运算器、控制器、存储器、输入设备和 输出设备
思迅软件成功客户案例集-商锐9(2013) 2011公司简介.
存储器的层次结构 512KB~8MB 400GB/S 1~8GB 12GB/S CPU Cache RAM 500GB DISK
第2章 Intel IA-32/Intel 64处理器 结构与原理
資訊科技教育電子學習系列: 有效應用「課程為本學與教資源庫」 於初中科技與生活科 / 家政科的學與教
第8章 现代微型计算机 x86系列微处理器 8.2 微型计算机体系结构 8.3 存储管理技术 8.4 多任务管理与I/O管理
第八章 符号表 符号表的作用: 一致性检查和作用域分析; 辅助代码生成..
Chapter 4 歸納(Induction)與遞迴(Recursion)
汇编语言程序设计 Assembly Language Programming
陳維魁 博士 儒林圖書公司 第七章 參數的傳遞 陳維魁 博士 儒林圖書公司.
指令集架構 計算機也跟人類一樣,需要提供一套完整的語言讓人們跟它充分溝通,以完成正確的計算工作。
基于硬件辅助的内核漏洞挖掘框架 闫广禄.
CHAPTER 8 VIRTUAL MEMORY
5 Computer Organization (計算機組織).
第2章 16位和32位微处理器 位微处理器8086/ 位微处理器80386
C 程式設計— 控制敘述 台大資訊工程學系 資訊系統訓練班.
递推算法 递推是一种重要的数学方法,在数学和计算机领域都有广泛应用。这种算法的特点是:一个问题的求解需要一系列的计算,在已知条件和所求问题之间总存在某种相互联系的关系。在计算时,可以找到前后过程间的数量关系,即递推。递推算法包括顺推和逆推。 递推算法的关键在于找到相邻数据项之间的关系,即递推关系,建立递推关系式。我们有时将递推算法看成一种特殊的迭代算法。
第六章 运行时存储空间的组织和管理 术语 本章内容 讨论一个活动记录中的数据布局 程序执行过程中,所有活动记录的组织方式 过程的活动
Course 9 NP Theory序論 An Introduction to the Theory of NP
第3章 IA-32指令系统 3.1 基本数据类型 3.2 IA-32的指令格式 3.3 IA-32指令的操作数寻址方式
計算機結構 – 概論 陳鍾誠 於金門大學.
一个非常简单的CPU的设计 1、组合逻辑控制器 2、微程序控制器.
第一章 8086程序设计 第二章 MCS-51程序设计 第三章 微机基本系统的设计 第四章 存贮器与接口 第五章 并行接口
重點 資料結構之選定會影響演算法 選擇對的資料結構讓您上天堂 程式.
中间代码生成.
組合語言和程式範例.
資料庫 靜宜大學資管系 楊子青.
软件工程 第四章 软件设计 软件过程设计技术与工具.
The Processor: Datapath and Control (Multi-cycle implementation)
5-6 串列埠模式0輸出埠擴充實習.
中国科学技术大学计算机系 陈香兰 2013Fall 第七讲 存储器管理 中国科学技术大学计算机系 陈香兰 2013Fall.
计算机系统结构(2012年春) ----存储层次: Cache基本概念
陳維魁 博士 儒林圖書公司 第三章 變數與繫結 陳維魁 博士 儒林圖書公司.
第2章 80x86计算机组织  计算机系统  存储器  中央处理机  外部设备.
北投溫泉博物館 建築特色 ★小組成員:高103林孟璇、林念儀、施妤柔★.
虚拟机加密,是把源程序的X86指令变成自定义的伪指令,执行时内置在保护程序中的VM就会启动,读取伪指令,然后解析执行
作业3、4、6、7 俞天灿.
問題解決與流程圖 高慧君 台北市立南港高中 2006年12月22日.
目 录: 一、网络存储系统的登录 二、网络存储系统的基本使用 三、学生提交作业功能的使用 四、教师开放资源功能的使用.
本节内容 通用寄存器 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
清华大学计算机科学与技术系高性能计算研究所 郑纬民 教授 2005年5月
大数据搜索挖掘实验室 第五章 子程序设计 张华平 副教授 博士 Website: 大数据搜索挖掘实验室
MATLAB 結構化財務程式之撰寫 MATLAB財務程式實作應用研習 主題五 資管所 陳竑廷
PASCAL语言 吉林大学计算机科学与技术学院.
講師:劉俊民(金剛) Idea 創意應用科技有限公司
Presentation transcript:

寄存器分配 影响程序速度的因素 cpu, register, cache, memory, disk 寄存器分配是“后端”的三个重要任务之一。 getreg 书上的办法。

寄存器分配的概念 register allocation decides which program values shall reside in registers register assignment picks the specific register in which these values will reside. (eax? edx?)

Memory Model Register-to-register model Assume IR program variable names are virtual registers. The allocator’s task is to map the set of virtual registers onto the registers provided by the target machine, called physical registers. In this scheme, the allocator inserts additional loads and stores for those virtual registers that cannot be allocated a phisical register. Memory-to-memory model Assume IR program variable names are memory references. The allocator determines when it is both safe and profitable to promote values into registers.

决定什么变量可以放在寄存器是tricky main() { int *A, *B, i, j; int C[100], D[100]; if (fee()) { A = C; B = D; }else { B = C; } j = fie(); for (i=0; i<100; i++) A[i] = A[i] * B[j]; B[j] 是循环不变量且可以放在寄存器吗?

决定什么变量可以放在寄存器是tricky subroutine fum integer x, y ... call foe(x,x) call foe(x,y) end subroutine foe(a,b) integer a, b a 和 b 可以放在寄存器里面吗?

决定什么变量可以放在寄存器是tricky var i: integer; p: ^integer; begin i:=8; p := @i; for i:=0 to 9 do writeln(p^); end i 可以放在寄存器里面吗?

决定什么变量可以放在寄存器是tricky c 的 memory specifier: volatile register 因此,我们下面的讨论假设Register-to-register model ,而把决定什么变量可以放在寄存器交给分析器或中间代码生成器。

寄存器类 寄存器并不都是一样的,如IA-32 有6+2个通用寄存器: EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP 。 有若干个特殊寄存器,CS, DS, SS, ES, FS, GS… EFlags, EIP MMX FP XMM 调试、测试寄存器等。

寄存器分配很难 寄存器类之间有复杂的interaction,如 mul, imul指令不能与浮点数指令并行执行; MMX, SIMD指令不能和浮点指令同时执行 即使是单类,最优算法也是NP完全问题。不存在多项式算法

寄存器分配约定 k个机器寄存器,n个虚拟寄存器,n>k spill: 某些虚拟寄存器不能分配到物理寄存器,其值在使用时用load指令装入,定义时用store指令保存。

简单的寄存器分配策略 原则:用得最多的变量应该放在寄存器里 算法: 1) 计算频率(使用计数usage counts) 2) 排序 3)分配 (注意不能把k个物理寄存器用光,应留几个用于处理内存变量的装入和存储) 4)重写代码

例子 频率: X 5 Z 5 Y 5 D 3 E 1 如果只有三个寄存器,可以分配两个给 X, Z,留下一个作临时寄存器 LOOP: X = 2 * E Z = Y + X + 1 IF some condition THEN Y = Z + Y D = Y - 1 ELSE Z = X - Y D = 2 ENDIF X = Z + D Z = X ENDLOOP

问题 使用计数计算很难。特别是在非基本块,如循环中。 即使一个变量的使用计数高,其使用也可能很不均匀,没有必要一直占用一个寄存器 推而广之,由于优化的关键在循环,任何基本块的分配策略都很难是高效的。

全局寄存器分配 全局一般指一个过程(函数)以上。我们仅讨论过程。 IBM的Chaitin在Yorktown Heights的Watson研究中心的工作。第一个基于图着色的全局寄存器分配器 。 Rice大学的Briggs的改进。 参见我ftp上的有关论文。

几个概念 生存期(live range/lifetime): 变量的定义和使用的期限。可以用def-use链来表示。如果两个def-use链有共同的use,则视为同一个生存期。 如果两个变量的生存期交叠(overlap),则不能使用同一个寄存器,称为冲突(interfere)。 一个生存期应该用同一个虚拟寄存器命名,可以分配一个机器寄存器。在分配之后,任意一个机器寄存器通常对应几个生存期。

图着色问题 生存期:顶点 冲突:边 着色:给每个顶点一种颜色,相邻的顶点不能用同样的颜色 k-着色:能用k种颜色着色。一个冲突图有k-着色表示最多需k个寄存器。 So I regard the success of this approach, which has been the basis for much future work, as a triumph of the power of a simple mathematical idea over ad hoc hacking. --Gregory Chaitin

Yorktown 分配器 Chaitin和他的同事在IBM的Yorktown Heights研究中心为PL8 编译器实现的分配器的流程

说明 Renumber 找到函数中的所有生存期,并给它们以唯一的编号。 Build 这一步要建立冲突图G。为了保证效率,G同时有两种表示形式:一个三角位矩阵(triangular bit matrix)和一个邻接向量表。 Coalesce 在这个阶段分配器删去不要的复制赋值,从代码中去掉对应的复制语句,合并源生存期和目标生存期。删去一个复制的前提是源和目标互相不冲突。我们把结点l i 和 l j 的合并记为 l ij 。 删去复制指令必然会改变冲突图,我们要重复build 和 coalesce直到再没有复制赋值。

说明 Spill Costs 在着色之前,对每个生存期 l 都要计算它的spill开销。l 的spill开销是对spill l 后插入的load 和store指令造成的开销的评估。每条指令的开销用10d加权,而d是这条指令的循环嵌套深度。 Simplify 这个阶段,还有select ,一起对冲突图着色。simplify 反复地检查G中的结点,删去所有度数小于k的结点。当一个结点被删去时,与它关联的边也被删去,然后这个点被压入栈s。 如果遇到G中剩下的每个结点的度数都大于k,就要选择其中一个spill。但不会立刻把结点对应的生存期spill(也就是立刻更新代码和冲突图),只是把那个结点从G中删去,并标记为spilling。

说明 最后G会成为空图。如果有些结点被标记spilling,它们在spill code 阶段会被spilled,整个分配过程要重新来。否则,栈s被传递到select阶段。 Select 按照在simplify阶段确定的顺序,把颜色分配给每一个结点。按顺序,每个结点从栈s中弹出来,重新插入到G中,并分配一个与它的邻居不同的颜色。 Spill Code 在每个被spilled的生存期的引用前面插入一条load指令,在每个被spilled的生存期的赋值后面插入一条store指令。

识别生存期(Discovering Live Ranges) 每个分离的使用就是一个唯一的生存期,被分配器来着色。因此,分配器的首要任务是识别函数中的生存期。在实现中,每个生存期被给予一个唯一的索引,按照生存期索引重写中间代码,代替原来的虚拟寄存器号。 识别生存期首先要找到可以合并的def-use链。一根def-use链把一个虚拟寄存器的赋值和它所有的使用串联起来。如果几根def-use链共享同一个使用(换句话说,几个赋值可以到达一个使用),这几根def-use链是可以合并的。当然,那些从一个给定的赋值出发的链都是可以合并的。

冲突(Interference) 理解冲突的概念是理解图着色法分配器的关键。Chaitin给出了判断冲突的条件:如果两个生存期互相冲突,那么在函数中存在某些点以及某次运行满足: 两个生存期都被定义(赋值), 两个生存期都会被使用,而且 两个生存期有不同的值。 这些条件通常是不可判定的。Chaitin给出了一种近似条件。

Chaitin的近似 在每个运算时刻,那些生存期是活跃的且可用的? 我们称一个关于变量v的生存期l在某条语句s是活跃的,如果存在一条路径从s到v的某个使用,而且在这条路径上不存在对v的赋值。类似的,称l在s是可用的如果存在一条路径从v的赋值到s。事实上,可用性和活跃性对应了上面的条件1和条件2,是原来的不可判定条件的保守的近似。

Chaitin的近似 对第三个条件,Chaitin 通过对复写操作特殊处理来做了近似。显然,复写使源和目的生存期具有相同的值,所以不一定冲突。因此有可能合并。

冲突图(Interference Graph) 在Yorktown 分配器中一个核心数据结构就是冲突图。冲突图要提供5个操作。 new(n) 返回一个n个结点的图,但是没有边。 add(g,x,y) 返回图g,并在结点x和y之间添加一条边。 interfere(g,x,y) 如果图g中结点x和y之间存在一条边就返回真。 degree(g,x) 返回图g中结点x的度数。 neighbors(g,x,f) 对图g中结点x的各个邻居应用函数f。

在实现中,冲突图有两种表现形式:三角位矩阵和邻接向量表。位矩阵可以支持常数时间的add和interfere操作,而邻接向量表是neighbors的高效表示,存储在一个连续的数组里。 构造冲突图: 1)为位矩阵分配空间和清零。对整个代码做一遍扫描,填充位矩阵并计算每个结点的度数。 2)知道每个结点的度数以后,为邻接表分配空间,并从位矩阵直接生成。

实现的时候,每一遍对流图中的每个基本块逆向扫描,动态维护一个当前活跃并且可用的生存期的集合。每遇到一处赋值,为被赋值的生存期和s中的所有元素在图中添加边。 彻底完成build—coalesce循环后,位矩阵占据的空间可以被释放。邻接表在以后的阶段simplify 和select中还需要。

合并(Coalescing) 建立冲突图以后,就要执行合并。对每个复制指令,检查它的源生存期和目的生存期是否冲突;若不冲突,它们可以被合并,复制指令也被删去。为了合并两个生存期l x和l y 成为l xy,在用到l x、l y每个地方用l xy代替。当两个生存期l x和l y被合并,必须更新冲突图,使得l xy和l x、l y的邻居冲突。 合并阶段对中间代码做一遍完全的扫描,尽可能地合并,更新冲突图。 任一个复制语句被删去,都会导致重建冲突图,并引起更多的合并。这个周期一直重复到没有更多的复制语句被删去才停止。

为什么删去复制语句后必须重建冲突图

Spilling 最粗糙的对spilling的处理方案就是:spill一个生存期l,然后在l的每处赋值后面插入store指令,在l的每处使用前面插入load指令。Chaitin 描述了几种情况下可以改进: 如果被spilled的生存期的两个使用是紧相邻的,就不必要为第二次使用从内存中重新读入;为这两个使用分配同一个寄存器就行了。 如果一个使用紧跟在被spilled的生存期的赋值的后面,也就不必要在使用前重新读入了。 类似的,如果一个生存期的所有使用都紧跟着对它的赋值,这个生存期也不必被spilled。

着色(Coloring) Yorktown 分配器的核心就是它的着色算法。Chaitin的算法分为两个部分simplify和select。 Simplify不断地把结点从图中删去,压入栈中。在select阶段,结点被从栈中弹出来,重新加到图中去。当结点l i的度数小于k时,它被从图中移入栈中。以后l i从栈中移回图中时,它的邻居数目仍然小于k。显然l i 在图中是可以着色的。

insight: 设G中有一个结点n的度数小于k, 且称G删去n后成为G’. G’可k着色 则 G可k着色。 在simplify阶段,只有确认一个结点在当前图中可以着色,才把它删去。当每一个生存期被删去时,它的邻居的度数就会降低。在select阶段,结点按照被删去的逆序分配颜色。

如果在simplify阶段遇到一个图中所有的结点的度数都大于k的情形,有一个结点将被选中spill。这个spill结点被从图中删去,并被标记为spilling。一个处理方案是在程序中的这一点立刻插入代码,重建冲突图,寻找新的着色方案。这个方案虽然精确但开销巨大。Chaitin提到一种不很精确的处理方案:在选择spill结点后,继续简化(simplification)直到走完这一遍,标记出所有的spill结点。

选择spill结点 选择使Mn最小的结点n去spill。其中, degreen是指结点n当前的度数。 这个公式的直观意义: 2)希望能尽量化简图(分母)

Briggs的改进 Briggs发现了Chaitin的算法的缺陷,产生了不必要的spill。两个例子,一小一大,可以展示算法的缺陷。 假设我们要为右图找到一个2着色方案。显然存在这样的方案;比如, x和y着红色,w和z着绿色。

如果运用Chaitin的算法,因为图中没有度数小于2的结点,必然有一个结点要被spill。 再看下一个例子

Briggs用上图的例程做测试的时候,发现分配器把循环计数变量和循环计数的上界(M,N,I,J)spill出去了,尽管当时还有可分配的寄存器。 原因:当必须spill时,这些小而短的生存期的spill开销小。 但这并不解决问题。最后的结果就是:那段复制数组的循环代码几乎就没有利用寄存器。

问题的进一步分析 Chaitin把 “n得到一个颜色”近似为“n的度数<k”. 这是充分条件,而不是必要条件,因为n的邻居得着色可能相同(第一个例子) 分配器不知道有些spill不减轻负担。导致过多的spill.

Briggs的改进 Briggs对Chaitin的算法做了两处修正: 在simplify阶段只要发现剩下的结点的度数都不小于k,就从中间选择一个spill。这个结点被从图中删去,但是并没有被标记为spilling。它被压入栈,以后有可能获得一个颜色。 在select阶段发现不能为某些结点着色时,就放弃那个结点,继续对下面的结点着色。那些被放弃的结点在Chaitin的算法中一定被spill。

spill决定现在由select而不是simplify作出 Briggs改进后的分配器的流程 spill决定现在由select而不是simplify作出

推迟spill产生两个结果 首先,它消除了一些无效的spill。在Chaitin的方法中,spill是在着色以前的simplify阶段就决定了。一旦一个结点被spilled,它对应的生存期就被spilled。在Briggs的方法中,那些结点放在栈里只是spill的候选者,由select阶段才决定它们是否真的被spilled。

其次,它提供了一个更强大的着色算法。在为结点x选择颜色的时候,它检查x的当前所有邻居的颜色。如果有两个或者多个x的邻居收到同样的颜色,即使x的度数不小于k,它也可以被染色。这就比Chaitin简单地用“x的度数是否小于k”作为判据要准确。这样实现的分配器可以为上面的菱形图产生一个2着色方案。

再看SVD例程 生存期I,J,M和N较早成为spill的候选者,因为它们的spill开销小。然而,spill它们并不会减轻循环内部的寄存器分配的压力。分配器不得不spill那些大而长的生存期。等到这些小的生存期从栈中弹出来,已经有些大的生存期被spilled了。通过了解小生存期的邻居的颜色,分配器很容易地为它们在复制循环中的分配颜色。

结果 Chaintin的算法称为悲观(pessimistic)着色算法;Briggs的算法称为乐观(optimistic)着色算法 Briggs的算法比Chaintin的算法有较大的改进:使spill开销平均降低20%(在IBM RS/6000的XL编译器进行SPEC基准测试时)

其他 Briggs还作了很多其他的改进,参见其博士论文。包括部分源程序。 寄存器分配是一个比较热门的编译课题,我们讲的这些也只是点皮毛而已。但这已经比书上的要复杂很多。可见书的更新太慢。 大家在以后的学习工作中要善于从其他地方获取知识(当然web是一个不错的选择)