CSAPP Notes ML Programming
CSAPP Notes: ML Programming
Computer System - Notes: ML Programming
本课程主要使用 x86 指令;CISC(复杂指令集);
ARM 属于 RISC (精简指令集);
g++
和 gcc
g++
和 gcc
都是 GNU Compiler Collection(GNU 编译器集合)中的工具,用于编译源代码并生成可执行文件。然而,它们之间有一些区别:
- g++:
g++
是 GNU 编译器集合中专门用于编译 C++ 源代码的工具。- 当你使用
g++
编译时,它会默认将源代码视为 C++ 代码,然后应用 C++ 相关的语法和标准库。 - 如果你使用
g++
编译一个 C++ 源文件,它会自动链接 C++ 标准库。 - 例如:
g++ main.cpp -o main
- gcc:
gcc
是 GNU 编译器集合中通用的编译器,可以用于编译多种编程语言,包括 C、C++、Objective-C 等。- 当你使用
gcc
编译时,它会根据文件的扩展名来确定是 C 还是 C++ 代码。.c
扩展名会被视为 C 代码,.cpp
扩展名会被视为 C++ 代码。 - 对于 C++ 代码,
gcc
会自动调用g++
来处理。 - 如果你使用
gcc
编译 C++ 源文件,同样会链接 C++ 标准库。 - 例如:
gcc main.cpp -o main
流程
- 预处理阶段(Preprocessing):
- 输入:
.cpp
、.h
等源文件。 - 输出:
.i
文件。 - 过程:在此阶段,预处理器执行宏展开、文件包含等操作,生成一个经过预处理的源代码文件。
- 输入:
- 编译阶段(Compilation):
- 输入:
.i
文件。 - 输出:
.s
文件。 - 过程:编译器将经过预处理的源代码翻译成汇编语言代码。
- 输入:
- 汇编阶段(Assembly):
- 输入:
.s
文件。 - 输出:
.o
文件。 - 过程:汇编器将汇编语言代码翻译成机器代码,并生成目标文件(
.o
文件)。
- 输入:
- 链接阶段(Linking):
- 输入:
.o
文件、库文件等。 - 输出:可执行文件(通常无后缀名,或
.exe
、.out
等,取决于操作系统)。 - 过程:链接器将目标文件以及可能的库文件链接在一起,解决符号引用,生成最终的可执行文件。
- 输入:
常用参数
-
编译参数:
g++ source.cpp
:编译source.cpp
文件并生成默认输出文件a.out
。g++ source.cpp -o output
:编译source.cpp
文件并将可执行文件命名为output
。
-
指定编译阶段:
-c
:只进行编译,不进行链接,生成目标文件(.o
文件)。- 预处理->编译->汇编
-S
:只进行预处理和编译,不进行汇编和链接,生成汇编代码文件(.s
文件)。- 预处理->编译
-E
:只进行预处理,不进行编译等等,生成的仍然是.cpp
文件;
-
预处理选项:
-E
:只进行预处理,将预处理结果输出到标准输出。
-
优化选项:
-
-O0
、-O1
、-O2
、-O3
:指定不同级别的优化。-O0
表示不进行优化,-O3
表示最高级别优化。 -
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
优化级别:
- -O0: 这是最低级别的优化,代码将不会进行任何优化处理。这对于调试和分析非常有用,因为生成的代码将与源代码相匹配,但可能会导致较低的性能。
- -O1: 这个级别启用了一些基本的优化,如去除冗余的计算和一些常见的性能改进。代码的执行速度可能会稍有提升,但仍然保持着较好的调试友好性。
- -O2: 在这个级别,编译器会执行更多的优化,包括内联函数、循环展开等。这会带来显著的性能提升,但有些情况下可能会导致一些调试信息的丢失。
- -O3: 这是更高级别的优化,编译器会进行更多的变换,以提高代码的执行速度。然而,这可能会导致一些副作用,如增加代码大小和编译时间。
- -Os: 该选项会优化代码的大小,即尽量减小生成的可执行文件的大小,而不是追求最大的性能提升。
- -Og: 此选项用于 "优化用于调试",会在保留调试信息的前提下,进行一些基本的优化,以平衡调试友好性和性能。
- -Ofast: 这是一个极高级别的优化选项,会启用所有的优化,并可能会违反一些标准的语义,以实现更高的性能。但这可能会导致一些不符合预期的行为。
-
-
链接选项:
-l<library>
:链接指定的库。例如,-lm
链接数学库。-L<dir>
:指定搜索库文件的目录。
-
头文件包含路径:
-I<dir>
:指定头文件的搜索路径。
-
其他常用选项:
-std=<standard>
:指定使用的 C++ 标准,例如-std=c++11
。-Wall
:开启所有警告信息。-g
:生成调试信息,用于调试程序。-Werror
:将警告视为错误。-pedantic
:严格遵循标准规范,发出更多警告。
例
程序清单
#include <iostream>
using namespace std;
int main() {
cout << "Hello world!" << endl;
int x = 1;
int y = 2;
int z = 3;
return 0;
}
-
-c
:只进行编译,不进行链接,生成目标文件(.o
文件)。-
预处理->编译->汇编
-
g++ test.cpp -Og -c
-
可以用
objdump
或者nm
等工具查看目标文件-
objdump -d test.o # 查看目标文件的汇编代码 nm test.o # 列出目标文件中的符号表信息
-
-
-
-S
:只进行预处理和编译,不进行汇编和链接,生成汇编代码文件(.s
文件)。- 预处理->编译
g++ test.cpp -Og -S
(生成一个 600 行左右的汇编代码)
-
-E
:只进行预处理,不进行编译等等,生成的仍然是.cpp
文件;- 预处理
g++ test.cpp -Og -E -o test.pre
(会变成一个六万行左右的cpp代码)- 预处理会进行一些操作,比如:
- 宏展开
- 头文件包含
- 条件编译
- 删除注释
- 生成行号信息
- 大体上可以理解为 copy and paste
Assembly
Disassembling Object Code: Disassembler
objdump -d ___
例
> g++ --version
Apple clang version 14.0.3 (clang-1403.0.22.14.1)
Target: arm64-apple-darwin22.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
到汇编就停下:
g++ test.cpp -Og -S
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 13, 0 sdk_version 13, 3
.globl __Z6my_sumii ; -- Begin function _Z6my_sumii
.p2align 2
__Z6my_sumii: ; @_Z6my_sumii
.cfi_startproc
; %bb.0:
add w0, w1, w0
ret
.cfi_endproc
; -- End function
.globl _main ; -- Begin function main
.p2align 2
_main: ; @main
.cfi_startproc
; %bb.0:
mov w0, #0
ret
.cfi_endproc
; -- End function
.subsections_via_symbols
先生成可执行文件,再反汇编
g++ test.cpp -Og -o test.o
`objdump -d test >> test.txt`
test.o: file format mach-o arm64
Disassembly of section __TEXT,__text:
0000000100003fa8 <__Z6my_sumii>:
100003fa8: 20 00 00 0b add w0, w1, w0
100003fac: c0 03 5f d6 ret
0000000100003fb0 <_main>:
100003fb0: 00 00 80 52 mov w0, #0
100003fb4: c0 03 5f d6 ret
可以看到生成的汇编代码会短一点,因为丢失了一些信息;
等下,这个课程用的是 x86 的汇编()
换个机器先——
> g++ --version
g++ (GCC) 8.3.1 20190311 (Red Hat 8.3.1-3)
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.