1、编译器三级优化分别优化了哪些?
2、总结gcc静态库和动态库的制作;
3、总结CMake用法;
GNU编译器提供-O选项供程序优化使用:
-O 提供基础级别的优化
-O2 提供更加高级的代码优化,会占用更长的编译时间
-O3 提供最高级的代码优化
-O4 不优化,这是默认值
第一级:代码调整
代码调整是一种局部的思维方式;基本上不触及算法层级;它面向的是代码,而不是问题; 所以:语句调整,用汇编重写、指令调整、换一种语言实现、换一个编译器、循环展开、参数传递优化等都属于这一级;这个级别试图执行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-reload
二、总结gcc静态库和动态库的制作
1.静态库
1.创建
首先对c文件进行gcc -c 源文件.c 生成 .o文件 ar rcs lib+名称.a .o文件
2.使用
gcc main.c lname(文件的名称需要去掉lib) -L(指在当前路径下)
2.动态库
1.创建
gcc -shared-fPIC-o 库名.so 源文件.c
2.使用
gcc 源文件.c./ 库名.so-o 可执行文件名
CMake用法总结
CMakeLists.txt首部增加对CMake的版本限制:
CMAKE_MINIMUN_REQUIRED(VERSION 2.6)
定义工程名:
PROJECT (MyProject [CXX] [C] [JAVA]) //默认支持所有语言
输出提示信息:
MESSAGE ([SEND_ERROR | STATUS | FATAL_ERROR] “message”)
生成可执行对象:
ADD_EXECUTABLE (MyExe ${SRC_FILES})
生成子目录下的模块或程序并放在build的相应子目录下:
ADD_SUBDIRECTORY(source_dir [binary_dir])
制定二进制目标的保存位置:
无论是否在ADD_SUBDIRECTORY中制定了编译输出目录,都可以制定最终二进制的位置
SET (EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET (LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
在哪里ADD_EXECUTABLE或ADD_LIBRARY,就在哪个CMakeLists.txt中放上述的定义
设置变量:
SET (variable_name variable_value)
增加配置文件模板,用来生成源码中可用的头文件:
CONFIGURE_FILE(
"${PROJECT_SOURCE_DIR}/[图片]TutorialConfig.h.in"
"${PROJECT_BINARY_DIR}/TutorialConfig.h"
)
该用法中,模板文件主要有以下用法:
a. /// @variable_name@ 部分会替换成为CMAKE里设置的变量的值
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
b. /// #cmakedefine variable_name 会根据CMAKE文件中变量是否为真决定是否要定义该变量
#cmakedefine variable_name
增加INCLUDE目录:
INCLUDE_DIRECTORIES ("${PROJECT_BINARY_DIR}")
载入其他cmake文件:
INCLUDE (file1)
INCLUDE (module)
生成静态库、动态库:
ADD_LIBRARY (MyLib [SHARED | STATIC | MODULE] “${SRC_FILES}”)
增加链接对象:
TARGET_LINK_LIBRARIES (MyExe “${LIB_NAMES}”)
制定编译选项的内置变量:
CMAKE_C_FLAGS,设置C编译选项,也可以通过ADD_DEFINITIONS()添加
CMAKE_CXX_FLAGS,支持C++编译选项,也可以通过ADD_DEFINITIONS()
增加选项以及逻辑判断(样例):
OPTION(USE_MYMATH “Use tutorial provided math implementation” ON)
IF (USE_MYMATH)
INCLUDE_DIRECTORIES ("${PROJECT_SOURCE_DIR}/MathFunctions")
ADD_SUBDIRECTORY (MathFunctions)
SET (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
ENDIF (USE_MYMATH)
同时相应增加代码中的#ifdef USE_MYMATH逻辑
有IF的地方一定要有ENDIF,有ELSEIF的地方ENDIF可选
IF (expression1)
COMMAND1
COMMAND2
ELSE (expression1)
command1
command2
ENDIF (expression1)
IF (WIN32)
COMMAND1
ELSEIF (UNIX)
COMMAND2
ELSEIF (APPLE)
COMMAND3
ENDIF (WIN32)
CMake中系统信息的内置变量:
CMAKE_SYSTEM,系统名称,比如Linux-2.6.22
CMAKE_SYSTEM_NAME,不包含版本的系统名,比如Linux
UNIX,所有的类UNIX平台上为TRUE,包括OS X和cygwin
WIN32,所有win32平台上为TRUE,包括cygwin
CMake常用变量:
CMAKE_BINARY_DIR & PROJECT_BINARY_DIR,执行cmake的目录。
CMAKE_SOURCE_DIR $ PROJECT_SOURCE_DIR,工程顶层目录
CMAKE_CURRENT_SOURCE_DIR,当前处理的CMakeLists.txt的所在路径
CMAKE_CURRENT_BINARY_DIR,当前处理的CMakeLists.txt的输出路径
增加项目依赖:
ADD_DEPENDENCIES,定义target依赖其他target,保证在编译本target之前,其他target已经被构建。
ADD_DEPENDENCIES (target-name depend-target1 depend-target2)
文件操作:
FILE (WRITE filename “message to write”)
FILE (APPEND filename “message to write”)
FILE (READ filename variable)
FILE (GLOB variable [RELATIVE PATH] [GLOBBING EXPRESSIONS])
FILE (GLOB_RECURSE variable [RELATIVE PATH] [GLOBBING EXPRESSIONS])
FILE (REMOVE [DIRECTORY])
FILE (REMOVE_RECURSE [DIRECTORY])
FILE (MAKE_DIRECTORY [DIRECTORY])
设置make install的安装路径:
INSTALL (TARGETS Tutorial DESTINATION bin)
INSTALL (FILES “${PROJECT_BINARY_DIR}/TutorialConfig.h” DESTINATION include)
注意CMAKE_INSTALL_PREFIX变量,按如上方式分别会安装到 ${CMAKE_INSTALL_PREFIX}/bin ${CMAKE_INSTALL_PREFIX}/include
增加make test的测试用例:
// 用指定参数运行
ADD_TEST (${TestName} ${TargetName} ${ARGS})
// 检验输出结果中有没有制定的正则式的子串
SET_TESTS_PROPERTIES ( T e s t N a m e P R O P E R T I E S P A S S R E G U L A R E X P R E S S I O N " {TestName} PROPERTIES PASS_REGULAR_EXPRESSION " TestNamePROPERTIESPASSREGULAREXPRESSION"{RESULT_SUBSTRING}")
检测系统是否有某函数:
INCLUDE (CheckFunctionExists) 或者 INCLUDE (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
CHECK_FUNCTION_EXISTS (log HAVE_LOG)
CHECK_FUNCTION_EXISTS (exp HAVE_EXP)