2020-07-06

第一级:代码调整
代码调整是一种局部的思维方式;基本上不触及算法层级;它面向的是代码,而不是问题; 所以:语句调整,用汇编重写、指令调整、换一种语言实现、换一个编译器、循环展开、参数传递优化等都属于这一级;这个级别试图执行9种单独的优化功能:

-fdefer-pop
-fmerge-constans
-fthread-jumps
-floop-optimize
-fif-conversion: if-then
-fif-conversion2
-fdelayed-branch
-fguess-branch-probability
-fcprop-registers
第二级:新的视角
新的视角强调的重点是针对问题的算法;即选择和构造适合于问题的算法;(冒泡排序还是快排的选择问题是这一级早就应该完成的)很多经典算法都对问题作了一些假设(包括我们当前已经完成的算法实现),而在面对实际问题时“新的视角”提示我们应该重新检视这些假设,并尝试不同的思考问题的角度,寻求适合于问题的新算法; 编译器还试图采用以下几种优化。
10. -fforce-mem
11. -foptimize-sibling-calls
12. -fstrength-reduce
13. -fgcse
14. -fcse-follow-jumps
15. -frerun-cse-after-loop
16. -fdelete-null-pointer-checks
17. -fextensive-optimizations
18. -fregmove
19. -fschedule-insns
20. -fsched-interblock
21. -fcaller-saves
22. -fpeephole2
23. -freorder-blocks
24. -fstrict-aliasing
25. -funit-at-a-time
26. -falign-functions
27. -fcrossjumping

第三级:表驱动状态机
将问题抽象为另一种等价的数学模型或假想机器模型,比如构造出某种表驱动状态机;这一级其实是第二级的延伸,只是产生的效果更加明显,但它有其本身的特点(任何算法和优化活动都可以看作是他的投影);这一级一般可以产生无与伦比的快速程序, 要达到这一级需要大量修炼的;并且思考时必须放弃很多已有的概念或者这些概念不再重要,比如:变量、指针、空间、函数、对象等,剩下的只应该是那个表驱动状态机; 我想把这种境界描述为:空寂中,一些输入驱动着一个带有状态的机器按设定好的最短路线运转着;除此之外have nothing; 既:把解决一个问题的算法看作一个机器,它有一些可变的状态、有一些记忆、有一些按状态运行的规则,然后一些输入驱动这个机器运转;这就是第三级要求的思考优化问题的切入点,也就是寻找一部机器,使它运行经过的路径最短(可能是速度也可能是空间等等) 。编译器还试图采用以下这种优化方式。
28. -finline-functions
29. -fweb
30. -fgcse-after-relo
静态库

(1)制作步骤

1)编译.o文件

2)将.o文件打包:ar rcs libname.a file1.o file2.o file3.o ...

3)将头文件与库一起发布

文件内容及路径分布如下:

[root@centos1 calc]# tree
.
├── include
│ └── head.h
├── lib
├── main.c
└── src
├── add.c
└── sub.c

1 #include
2
3 int add(int a, int b);
4 int sub(int a, int b);
head.h

1 #include “head.h”
2
3 int main(void)
4 {
5 int a = 10, b = 10;
6
7 printf("%d + %d is %d\n", a, b, add(a, b));
8 printf("%d - %d is %d\n", a, b, sub(a, b));
9
10 return 0;
11 }
main.c

1 #include “head.h”
2
3 int add(int a, int b)
4 {
5 return a + b;
6 }
add.c

1 #include “head.h”
2
3 int sub(int a, int b)
4 {
5 return a - b;
6 }
sub.c
编译为.o文件
进入到 src 目录下执行:

[root@centos1 src]# gcc -c *.c -I …/include/
[root@centos1 src]# ll
总用量 16
-rw-r–r--. 1 root root 63 4月 20 14:53 add.c
-rw-r–r--. 1 root root 1240 4月 20 15:10 add.o
-rw-r–r--. 1 root root 63 4月 20 14:24 sub.c
-rw-r–r--. 1 root root 1240 4月 20 15:10 sub.o
将.o文件打包,制作成libCalc.a静态库
[root@centos1 src]# ar rcs libCalc.a *.o
[root@centos1 src]# ll
总用量 20
-rw-r–r--. 1 root root 63 4月 20 14:53 add.c
-rw-r–r--. 1 root root 1240 4月 20 15:10 add.o
-rw-r–r--. 1 root root 2688 4月 20 15:12 libCalc.a
-rw-r–r--. 1 root root 63 4月 20 14:24 sub.c
-rw-r–r--. 1 root root 1240 4月 20 15:10 sub.o
1.动态库 制作步骤

(1)编译与位置无关的代码(下图共享库),生成.o目标文件,关键参数 -fPIC

进程虚拟地址空间

(2)将.o文件打包,关键参数 -shared

(3)将库与头文件一起发布

生成.o目标文件
文件路径和内容同上,进入到src目录,生成.o目标文件:

[root@centos1 src]# gcc -fPIC -c *.c -I …/include/
[root@centos1 src]# ll
总用量 16
-rw-r–r--. 1 root root 63 4月 20 14:53 add.c
-rw-r–r--. 1 root root 1240 4月 20 15:20 add.o
-rw-r–r--. 1 root root 63 4月 20 14:24 sub.c
-rw-r–r--. 1 root root 1240 4月 20 15:20 sub.o
将.o文件打包生成动态库
[root@centos1 src]# gcc -shared -o libCalc.so *.o
[root@centos1 src]# ll
总用量 24
-rw-r–r--. 1 root root 63 4月 20 14:53 add.c
-rw-r–r--. 1 root root 1240 4月 20 15:20 add.o
-rwxr-xr-x. 1 root root 5817 4月 20 15:21 libCalc.so
-rw-r–r--. 1 root root 63 4月 20 14:24 sub.c
-rw-r–r--. 1 root root 1240 4月 20 15:20 sub.o

CMake使用
一、 基本使用

安装:下载二进制包后可直接解压使用

从源码安装则执行命令:./bootstrap; make; make install——尝试执行bootstrap失败

使用:cmake dir_path,生成工程文件或makefile文件

二、 概念

out-of-source build,与in-source build相对,即将编译输出文件与源文件放到不同目录中;

三、 基本结构

1,依赖CMakeLists.txt文件,项目主目标一个,主目录中可指定包含的子目录;

2,在项目CMakeLists.txt中使用project指定项目名称,add_subdirectory添加子目录

3,子目录CMakeLists.txt将从父目录CMakeLists.txt继承设置(TBD,待检验)

四、 语法

  1.   #注释
    
  2.   变量:使用set命令显式定义及赋值,在非if语句中,使用${}引用,if中直接使用变量名引用;后续的set命令会清理变量原来的值;
    
  3.   command (args ...)  #命令不分大小写,参数使用空格分隔,使用双引号引起参数中空格
    
  4.   set(var a;b;c) <=> set(var a b c)  #定义变量var并赋值为a;b;c这样一个string list
    
  5.   Add_executable(${var}) <=> Add_executable(a b c)   #变量使用${xxx}引用
    
  6.   条件语句:
    

if(var) #var 非empty 0 N No OFF FALSE… #非运算使用NOT

else()/elseif() … endif(var)

  1.   循环语句
    

Set(VAR a b c)

Foreach(f ${VAR}) …Endforeach(f)

  1.   循环语句
    

WHILE() … ENDWHILE()

五、 内部变量

CMAKE_C_COMPILER:指定C编译器

CMAKE_CXX_COMPILER:

CMAKE_C_FLAGS:编译C文件时的选项,如-g;也可以通过add_definitions添加编译选项

EXECUTABLE_OUTPUT_PATH:可执行文件的存放路径

LIBRARY_OUTPUT_PATH:库文件路径

CMAKE_BUILD_TYPE::build 类型(Debug, Release, …),CMAKE_BUILD_TYPE=Debug

BUILD_SHARED_LIBS:Switch between shared and static libraries

内置变量的使用:

在CMakeLists.txt中指定,使用set

cmake命令中使用,如cmake -DBUILD_SHARED_LIBS=OFF

六、 命令

project (HELLO) #指定项目名称,生成的VC项目的名称;

使用${HELLO_SOURCE_DIR}表示项目根目录

include_directories:指定头文件的搜索路径,相当于指定gcc的-I参数

include_directories (${HELLO_SOURCE_DIR}/Hello) #增加Hello为include目录

link_directories:动态链接库或静态链接库的搜索路径,相当于gcc的-L参数

   >> link_directories (${HELLO_BINARY_DIR}/Hello)     #增加Hello为link目录

add_subdirectory:包含子目录

   >> add_subdirectory (Hello)

add_executable:编译可执行程序,指定编译,好像也可以添加.o文件

   >> add_executable (helloDemo demo.cxx demo_b.cxx)   #将cxx编译成可执行文件——

add_definitions:添加编译参数

add_definitions(-DDEBUG)将在gcc命令行添加DEBUG宏定义;

add_definitions( “-Wall -ansi –pedantic –g”)

target_link_libraries:添加链接库,相同于指定-l参数

target_link_libraries(demo Hello) #将可执行文件与Hello连接成最终文件demo

add_library:

add_library(Hello hello.cxx) #将hello.cxx编译成静态库如libHello.a

add_custom_target:

message( status|fatal_error, “message”):

set_target_properties( … ): lots of properties… OUTPUT_NAME, VERSION, …

link_libraries( lib1 lib2 …): All targets link with the same set of libs

你可能感兴趣的:(笔记)