优化编译器
在计算机领域中,优化编译器是一种试图将程序的某种属性最大化或者最小化的编译器。一般而言,受影响的属性包括了计算机程序的大小、执行时间以及内存占用,不同的优化编译器会根据各自的着重点,对程序做出一定变换或者在不影响运行结果的情况下修改程序的结构,使得这些属性更贴近理论上的最优值。 优化编译器的核心是程序优化变换(optimizing transformations),该类算法的目的是将原有程序,替换成资源消耗更低、运行时间更短,但语义上与…
共 20 篇文章
在计算机领域中,优化编译器是一种试图将程序的某种属性最大化或者最小化的编译器。一般而言,受影响的属性包括了计算机程序的大小、执行时间以及内存占用,不同的优化编译器会根据各自的着重点,对程序做出一定变换或者在不影响运行结果的情况下修改程序的结构,使得这些属性更贴近理论上的最优值。 优化编译器的核心是程序优化变换(optimizing transformations),该类算法的目的是将原有程序,替换成资源消耗更低、运行时间更短,但语义上与…
窥孔优化是一种优化编译器技术,在编译的后面阶段,寻找编译器生成的特定的指令序列,将该序列替换成性能更好的等效指令序列。该算法的可视范围极小,往往只能同时窥看几条指令,故名曰窥孔优化(指其犹如通过窥孔观察程序)。被优化掉的这少量指令序列被称为窥视孔或窗口。 }} 外部链接 [ftp://ftp.cs.princeton.edu/pub/lcc/contrib/copt.shar The copt general-purpose peeph…
編譯器原理中,死碼消除(Dead code elimination)是一種編譯最佳化技術,它的用途是移除對程式執行結果沒有任何影響的程式碼。移除這類的程式碼有兩種優點,不但可以減少程式的大小,還可以避免程式在執行中進行不相關的運算行為,減少它執行的時間。不會被執行到的程式碼(unreachable code)以及只會影響到無關程式執行結果的變數(Dead Variables),都是死碼(Dead code)的範疇。 範例 下列的範例,以…
数据流分析是一种用于收集计算机程序在不同点计算的值的信息的技术。一个程序的控制流圖(control flow graph, CFG)被用来确定对变量的一次赋值可能传播到程序中的哪些部分。这些信息通常被编译器用来优化程序。数据流分析的一个典型的例子就是可到达定义的计算。 进行数据流分析的最简单的一种形式就是对控制流图的某个节点建立数据流方程,然后通过迭代计算,反复求解,直到到达不动点。这個方法是由蓋瑞·基爾多在海军研究生院任教时发明的。 …
迴圈判斷外提()是一種的方法。迴圈判斷外提將迴圈中的條件式移到迴圈之外,在「若」與「否則」式裡各放置一個原來迴圈的內容。這可以增進迴圈平行處理的可能性。 以下是一個簡單的例子。若程式碼想要將陣列 x、y 相加,並根據變數 w 做別的事,就有這種 C 的程式碼: int i, w, x[1000], y[1000]; for (i = 0; i 因為有迴圈裡的條件式,要安全的平行處理這個迴圈變得很困難。若進行判斷外提,這個迴圈會變成: i…
再具体化()是一种编译器优化技术,首先由格里高利·柴廷(Gregory J. Chaitin)等人于1981年提出并且被实现于PI.8编译器中。其通过重新计算某个值而不是从内存中加载该值的手段,来缩短程序运行时间。该技术可见于GCC等现代编译器中。 使用 这项技术通常见于寄存器配置领域之中,因为在遇到寄存器不足的场景时,一些变量会被转移至内存,形成溢出变量(spilled variable)。考虑到重新从内存加载某个溢出变量的延迟很长,…
在计算机科学中,代码生成是代码编译过程中的其中一个环节。在这个环节中,代码生成器会将某中間語言(IR)转换为机器可以执行的形式如机器码,或者另一门语言,如C语言代码。 工业级的编译器一般存在多个编译环节(Compiler pass)。第一个环节通常会将源代码转换成抽象语法树,而抽象语法树随后又会被转换成某种中间语言(IR)。编译器的中间环节会对这门中间语言进行各种变换以优化程序的性能。这种具有阶段性的编译方式,其优势在于允许编译器开发者…
在程式語言理論中,惰性求值(),又譯為惰性计算、懒惰求值,也稱為傳需求調用(call-by-need),是计算机编程中的一个概念,目的是要最小化计算机要做的工作。惰性计算的最重要的好处是它可以在空间复杂度上得到极大的优化,从而可以轻易构造一个无限大的数据类型。 惰性求值的相反是及早求值,这是一个大多数编程语言,如C语言,所使用的缺省计算方式。 由于翻译问题,该词在不同语境下有两个相关而又有区别的含意,可以表示为“延迟求值”和“最小化求值…
内联缓存()是部分编程语言的运行时系统采用的优化技术,最早为Smalltalk开发是一个常量寄存器加载,后跟一个调用指令。“未初始化(uninitialized)”状态称为“未链接(unlinked)”更佳。寄存器加载了消息选择器(通常是某个对象的地址),而调用是查找当前接收器的类中消息的一个例程,采用上面提过的一级方法查找缓存。然后,运行时例程重写指令,改变载入指令以载入具有当前接收器类型的寄存器,以及调用指令以调用目标方法的前导代码…
内联展开(或称内联,下文或交替使用)是一种将函数体直接展开到的一种优化技术。它可以由手工指定(如inline关键字),或者经由编译优化自动完成。内联展开类似于宏展开,区别在于内联展开在编译时完成,而宏展开则可能在预编译(如C/C++)、编译时(如Scheme)、运行时(如Scheme)时完成。 内联是一种重要的优化技术。内联的好处主要在于消除函数的调用开销(压栈,保护/恢复现场),但内联展开对于性能的提升不能一概而论,它可能导致生成的代…
在軟體工程領域,強度折減(Strength reduction)是一個編譯器最佳化技術,它將昂貴的運算以相同但是相對便宜的運算取代,最經典的範例就是將乘法轉換為使用迴圈的連續加法,這經常使用在陣列的定址。 強度折減的範例包含: 使用迴圈及加法取代乘法運算 使用迴圈及乘法取代指數運算 程式碼分析 大部份程式的執行時間通常都是花費在一些相當小的程式段,這些程式段通常都在迴圈之內不斷的執行。 編譯器使用一些方法來辨識迴圈以及迴圈內暫存器數值的…
在程序设计中,冗余代码又稱代碼冗餘,是指计算机程序中出現了不必要的源代码或编译代码,例如一些永远不会执行的代码就是屬於冗余代码。出現冗餘代碼後可以考慮將冗餘代碼刪除。 例子 以下是C语言的一個例子 int foo(int iX) { int iY = iX2; return iX2; } 其中int iY = iX*2表达式就是多余的代码,可以將其刪除。 参考文献
在计算机科学中,复制传播(copy propagation)是一种编译器优化技术,在GCC、LLVM等大型编译器中均有使用此技术。 假设有一直接赋值语句(direct assignment) x := y ,则 x 是其赋值目标, y 是这个赋值语句的值。那么复制传播便是将代码中所有出现的、能被替换的 x ,统统直接替换成该语句的值 y 的一个过程。 在计算什么赋值目标能被安全地替换时,复制传播经常会使用到定义可达性、use-def链、…
在计算机科学中,指令选择(Instruction selection)是编译过程中的其中一个环节,位于编译器后端。其工作是将中层的中间语言(IR)转换为底层的中间语言。对于一般的编译器,这个阶段会执行于指令调度和寄存器配置这两个阶段之前,因此该编译环节产出的IR一般允许程序中存在无限个伪寄存器(也作临时变量,Temporaries),并且窥孔优化依旧适用于该IR。忽略这些特性,该中间语言已经与目标的机器码、字节码或汇编语言非常相近。 例…
指令调度(instruction scheduling)是一种代码优化手段,常见于优化编译器,其主要功能在于通过加强指令层级的并行运行,使得程序在拥有指令流水线的中央处理器上能够高效运行。换句话说,此手段力求以不改变程序运算结果的方式,完成以下任务: 通过重组指令的运行顺序,减少或阻止流水线停顿的发生; 阻止非法操作(即未定义行为)的产生,例如涉及流水线时序、非互锁资源的等等操作。 其中流水线停顿主要由结构型冒险(受处理器的资源所限)、…
在電腦科學中,一個編譯程式定向是由程式師嵌入於原始程式碼的資料,以告知編譯器當「如何」編譯,其他原始程式碼則告知編譯器應當編譯「什麼」。 舉例 一個編譯器指令(compiler directive)可以告知編譯器在查核陣列索引時的範疇,或者信任程式師尚未編譯的程式碼,以免導致編譯錯誤。 在C程式語言中,使用「#include」的預處理器指導(preprocessor directive)可以告知編譯器在此處插入其他的純文字檔。 *在一些…
常數摺疊(Constant folding)以及常數傳播(constant propagation)都是編譯器最佳化技術,他們被使用在現代的編譯器中。進階的常數傳播形式,或稱之為稀疏有條件的常數傳播(sparse conditional constant propagation),可以更精確地傳播常數及無縫的移除無用的程式碼。 常量摺疊 常數摺疊是一個在編譯時期簡化常數的一個過程,常數在表示式中僅僅代表一個簡單的數值,就像是整數 2,若…
公共子表达式消除,又称CSE(),是一个编译器优化技术。在执行这项优化的过程中,编译器会视情况将多个相同的表达式替换成一个变量,这个变量存储着计算该表达式后所得到的值。 该优化技术十分常见,在现代各大编译器中(如LLVM、GCC)均有实现。 例子 考虑到下列代码: a = b c + g; d = b c + e; 可以观察到 b c 是两项表达式中的公共子表达式。如果计算这个子表达式并将其计算结果存储起来的开销,低于重复计算这个子表达…
在編譯器最佳化的領域裡,暫存器配置(Register Allocation)的用途,在於使一個在較少寄存器數量的CPU可使用較大數量的變數,暫存器配置可使用在一個基本區段(Basic block)(區域暫存器配置)、函數或程序(全域暫存器配置)、或是透過Call Graph進行跨函式邊域分析(跨程序暫存器配置),當完成每個函式或是程序,慣例上會要求每個呼叫函式的位置(Call site)必須插入儲存或是還原。 簡介 許多程式語言,程式設…
在電腦科學的領域,稀疏有條件的常數傳播(sparse conditional constant propagation)是一個优化的技術,常用在以静态单赋值形式(SSA)進行最佳化的編譯器,它可以移除程式中一些無用的程式碼以及進行常數傳播。然而,它比起死碼刪除以及常數傳播更加的強大。 這個演算法在SSA中藉由實現程式碼的抽象释义來運作。在實現抽象釋義的過程中,它使用常數的格(Lattice)以及在全域環境對應SSA變數到這個格的數值,演…