编译优化流程 1

Posted by 叉叉敌 on February 16, 2023

开篇

由于自己对编译器比较感兴趣,开始准备学习一些编译器相关的知识,目前学习路径是编译器原理、gcc 编译器优化、cuda 编程基础、(重点是掌握编译流程,执行流程、优化流程)。

由于没有相关的人的指点,是自己在网上找的学习资料,如果有不对的,请多多留言,谢谢~

小插曲

我开始在网上搜了下,关于这个博主的博客,真的解释了什么是从入门到放弃,从这一篇文章GCC 学习笔记(一)–编译流程,到第二篇文章,然后就没有然后了,估计是作者已经从事其他职业了吧。

可以查看这个大佬的博客,连续性比较高,从编译器的开发和优化文章来看,属于大佬了。

这里还找一个高校的编译器原理课程

学习路径

  1. 了解基本概念

首先需要了解 gcc 的基本概念,如编译过程、编译器前端和后端、语言前端和后端、优化器等。你需要了解 gcc 的基本原理和工作流程,并明确你了解的自身瓶颈。推荐《编译原理》一书进行了解。

  1. 学习熟悉 LLVM

GCC 是一款成熟的编译器,与基于 LLVM 的编译器类似,它也有类似的优化器(GCC 优化器)。因此,为了更好的理解和学习 GCC 优化器,建议先学习 LLVM。LLVM 是一种现代的编译器架构,并且与 GCC 类似,具有一个优化器。对于有一定经验的开发人员来说,学习 LLVM 可能更加容易。

  1. 了解 GCC 优化器

理解 GCC优化器功能极其重要,从而可以更好的编写更高质量,更快的代码。这部分主要学习 GCC 优化器、如何告诉 GCC 优化器做什么。

  1. 学习跟踪优化 (追踪 GCC 优化器)

追踪 GCC 优化器的方法将帮助你了解优化器如何处理你的代码。在跟踪期间,你应该看到优化器在各个阶段执行的转换,以及如何影响生成的机器代码。Gcov 优化器会打印日志,可通过可视化工具 Visualization Tools for GCC(Vtgcc)来直观的看到 GCC 优化器如何执行。

  1. 使用较小的项目进行实践

对于初学 GCC 优化器的开发人员,我建议使用小软件项目,如 smallcc 等小型 C 编译器进行实践。首先您需要实现一个较简单的编译器,以便于由此了解 GCC 代码库中的特定部分,如前端、后端和优化器等。

  1. 参考 GCC 文档

GCC 的官方文档是个极好的参考,可以获得示例代码、WIKI 文档、网页等。

以上列举的学习路径中,建议分配 50% 的时间用于实际练习。找到相关的开源项目,并尝试更改或添加代码之类的操作。通常,掌握编译器优化会涉及到编写各种插件,并尝试不同的编译器选项和标志,仅有经验,才能更好的发展技能。

编译流程

下面这个是最基础的,不好记,没关系,直接看gcc --help就可以看到了。

  -B <directory>           Add <directory> to the compiler's search paths.
  -v                       Display the programs invoked by the compiler.
  -###                     Like -v but options quoted and commands not executed.
  -E                       Preprocess only; do not compile, assemble or link.
  -S                       Compile only; do not assemble or link.
  -c                       Compile and assemble, but do not link.
  -o <file>                Place the output into <file>.

这里是编译过程的基本流程:

预处理(Preprocessing):cpp 命令产生原始代码,它会根据预处理指令(如 #include 或 #define 等)替换掉代码的部分部分,最终生成一个调整后的 .c 文件。

编译(Compilation):gcc -S 命令将 .c 文件转换成一个 .s 的汇编代码文件。

汇编(Assembling):as 命令将 .s 文件转换成一个 .o 的目标文件,它包含着目标计算机可以执行的机器语言代码。

链接(Linking):ld 命令把所有目标文件,以及必要的库文件连接在一起,生成可执行文件。

编译优化

GCC 编译器的优化点通常包括:

使用不同级别的优化选项:GCC 支持不同级别的优化选项,从 O0(无优化) 到 O3(高度优化)。优化级别越高,生成的可执行代码性能越好,但是可能会导致编译时间变慢。

使用不同的优化器策略:GCC 有几种优化器策略,如快速优化 (-O1)、基本优化 (-O2) 和生成最优代码 (-O3)。选择正确的优化器策略可以提高编译后优化后程序的性能。

使用 inline 关键字:inline 关键字告诉编译器将这个函数内联展开,它会自动选择最佳策略,并尝试减少函数调用的开销,从而提高程序性能。

避免不必要的中间代码:它使用了 ISO/IEC 14882 规范的 C++语言。在进行指令优化时,它的三个最基本的原则是提供初始化的自动变量、使用指针分析技术以及通过加了随机标签的单向链表来存储表示内存对象的情况。

show me the code

下面是一段 c 代码:

#include <stdio.h>

inline int add(int x, int y)
{
    if (x > 0) 
        y += 5;
    else 
        y -= 5;
    return x + y;
}

int main()
{
    int a = 10;
    int b = 5;
    int c = add(a, b);
    printf("Sum is %d\n", c);
    return 0;
}

对这段代码编译和执行:gcc -O3 -o test test.c, test就可以看到运行结果20了。

更多阅读

github 博客

微信公众号:cdtfug,欢迎关注一起吹牛逼,也可以加微信号「xiaorik」朋友圈围观。