目 录
第1章 CPU与编译器概论
1.1 高速路与人行道 002
1.2 编译器是如何运作的 003
编译后的汇编语言程序 004
添加优化选项后的结果 007
1.3 CPU是如何运作的 008
指令集架构与微架构 008
如何执行指令 009
指令流水线 011
高速缓存 012
深入探讨高速缓存 013
缓存块的替换算法 015
超标量指令执行 015
第1章 是不是偏离了主题 017
第2章 执行成本
2.1 两程序的执行成本 020
2.2 计·测·谋 020
书中的探讨 020
2.3 防止基准测试程序被优化 023
防止操作“归并” 023
防止变量在初始化时被优化 024
防止重复单一指令被优化 025
本书中的基准测试程序 026
2.4 验证——哪一步操作导致执行速度缓慢 029
2.5 基础加法与赋值运算 031
单一的赋值操作(寄存器间的传送) 032
单一的赋值操作(数据相互关联的情况) 032
常量赋值 033
变量间的加法运算 033
变量与常量相加 034
2.6 耗时的乘法运算 036
变量间的乘法运算 037
变量与常量相乘 037
2.7 更为耗时的除法运算 040
变量的除法(寄存器间的计算) 040
除数为2、4的除法运算 042
除数不是2的乘方的除法运算 042
无符号整数除法运算 042
除数为2的乘方时除法运算使用低成本移位指令 043
2.8 内存读取 045
小数组的读取(小范围内的内存操作) 045
大数组的读取(大范围内的内存操作) 047
与台式机的CPU进行比较 049
2.9 造成执行时间差别的判断语句 051
无else节点的if语句 051
带else节点的if语句 053
2.10 32/64位环境中不同的函数调用 053
2.11 实验总结 055
若想被爱则先爱 055
第3章 寻找性能瓶颈
3.1 使用gprof命令进行分析 058
gprof的使用方法 058
3.2 哪个环节在消耗时间 058
获取库函数的评测信息 060
耗时的函数 062
显示库函数的调用次数 063
3.3 函数的调用关系 063
3.4 进行数据分析的原理 066
3.5 其他性能分析器 067
培养高水平人才的教育系统 068
第4章 达人方法论
4.1 达人的关注点 072
硬件篇 072
编译器/中间件篇 074
算法篇 075
4.2 【硬件篇】数组和缓存的有效利用 076
矩阵的乘法运算 076
调整数组操作的顺序 077
展开循环的方式 078
矩阵的分块 079
4.3 【库函数篇】缓慢函数的迂回战术 080
strcmp函数为何缓慢 080
优化的陷阱 081
4.4 【硬件篇】使用SIMD进行字符串对比 083
4.5 【库函数篇】对比各种输入输出方法 085
行输入函数的对比 085
输出方法 089
管道输入输出的特殊案例 091
管道输入输出与文件输入输出 092
4.6 【算法篇】二分法查找与平衡二叉树 092
海量数据的分类 093
真要做到如此地步? 097
第5章 进一步研究编译器
5.1 不同级别的优化选项 100
GCC的优化选项 100
“零优化”对调试有效 100
以不出现未定义行为为前提的2级以上优化选项 101
5.2 优化·寄存器·外部变量 102
5.3 删除公共子表达式为程序瘦身 104
5.4 指针与复杂运算简化 105
5.5 将用户函数进行内联展开 106
和别人拉开差距! 108
第6章 给办公系统的一些启示
6.1 排序与字符串操作 112
6.2 小数点数的计算与字符串/数字的换算 112
块数据输入输出和字段分割 113
统计带小数部分的数 113
整数转换成字符串 115
性能优化的效果 116
6.3 半角字符转换为全角字符 117
判定字符的字节数 118
ASCII字符与半角片假名字符的判定 119
ASCII字符转换为全角字符 123
半角字符转换为全角字符 124
性能优化的效果 127
判定字符字节数的其他方法 127
有关UTF-8 130
6.4 探索具有某种数据特性的数组 132
数据的特性 133
二分法查找与线性查找相结合 135
性能优化的效果 138
后记 139