第1章 并行开发理论基础 1
1.1 并行相关概念 1
1.1.1 并发与并行、并行度 1
1.1.2 粒度 1
1.1.3 加速比及其定律 2
1.1.4 可扩展性与并行效率 4
1.1.5 负载均衡 4
1.1.6 吞吐量与延迟 4
1.1.7 热点与瓶颈 4
1.2 多核并行 4
1.2.1 多核软硬件现实 5
1.2.2 多核架构 5
1.2.3 多核并行手段 6
1.2.4 多核并行设计方法 7
1.2.5 多核多线程系统 8
1.2.6 多核多线程同步 9
1.2.7 多核多线程实现的问题 11
1.3 小结 11
第2章 英特尔Parallel Studio基础 12
2.1 英特尔Parallel Studio介绍 12
2.1.1 英特尔Parallel Studio背景 12
2.1.2 英特尔Parallel Studio的组成 12
2.1.3 英特尔Parallel Studio的特色 13
2.1.4 英特尔Parallel Studio的使用者 14
2.2 英特尔Parallel Studio快速上手 14
2.2.1 英特尔Parallel Studio的下载安装 14
2.2.2 选择案例 14
2.2.3 实践动手第一步:采用Parallel Studio运行串行程序 15
2.2.4 实践动手第二步:选用合适的实现对代码并行化 17
2.2.5 实践动手第三步:定位错误 18
2.2.6 实践动手第四步:性能优化 20
2.3 小结 23
第3章 英特尔Parallel Composer详解 24
3.1 Composer概述 24
3.2 英特尔C/C++编译器 25
3.2.1 自动并行和OpenMP并行 25
3.2.2 过程间优化 29
3.2.3 档案导引优化 29
3.2.4 编译器向量化 30
3.3 英特尔并行调试器 32
3.3.1 英特尔并行调试器概述 32
3.3.2 线程数据共享侦测 32
3.3.3 可重入函数调用侦测 34
3.3.4 SSE寄存器窗口 34
3.3.5 OpenMP多线程调试 35
3.3.6 并行区域的串行执行 36
3.4 英特尔TBB线程构建模块 36
3.4.1 英特尔TBB概述 37
3.4.2 功能模块分类与介绍 37
3.4.3 编译和运行TBB多线程程序 37
3.5 英特尔IPP性能基元 38
3.5.1 英特尔IPP概述 38
3.5.2 主要函数及其功能 39
3.5.3 编译和运行 45
3.6 小结 45
第4章 并行化方法 46
4.1 基本概念 46
4.1.1 Amdahl定律 46
4.1.2 进程与线程 47
4.2 并行化方法 48
4.3 并行化设计 49
4.3.1 任务划分 49
4.3.2 功能划分 51
4.3.3 并行化开发中的一些思考 51
4.4 案例分析:用蒙特卡罗方法计算π值 55
4.5 小结 58
第5章 英特尔Parallel Composer案例分析 59
5.1 案例5-1:Composer的使用——向量化和自动并行化 59
5.2 案例5-2:并行调试器的使用 62
5.3 案例5-3:通过TBB进行字符串查找 66
5.4 案例5-4:IPP压缩和解压缩案例介绍 69
5.5 小结 71
第6章 英特尔Parallel Inspector详解 72
6.1 Inspector概述 72
6.2 启动Inspectort 73
6.2.1 工作流程 73
6.2.2 启动 73
6.3 配置查找错误的类型和粒度 75
6.3.1 基于线程的相关错误及粒度 76
6.3.2 基于内存的相关错误及粒度 77
6.4 定位和解决发现的错误 79
6.4.1 检查错误 79
6.4.2 查看和分析错误 80
6.5 小结 81
第7章 软件纠错方法 82
7.1 基本概念 82
7.1.1 软件查错或纠错 82
7.1.2 白盒测试 82
7.1.3 黑盒测试 83
7.2 并行软件的纠错 84
7.3 线程并行的常见错误 84
7.3.1 线程间死锁 85
7.3.2 线程间竞争 86
7.3.3 内存泄露 87
7.4 小结 89
第8章 并行软件纠错案例 90
8.1 案例8-1:线程间相互作用导致的死锁问题 90
8.2 案例8-2:线程竞争 94
8.3 案例8-3:内存泄露 99
8.4 小结 101
第9章 英特尔Parallel Amplifier详解 102
9.1 Amplifier概述 102
9.1.1 如何开始Amplifier 102
9.1.2 如何使用符号信息 103
9.1.3 环境和对象 106
9.2 Amplifier的几个概念 107
9.3 Amplifier的分析运行 109
9.3.1 分析运行的几个选项 109
9.3.2 选择分析模式 110
9.3.3 如何选择分析模式 110
9.3.4 如何在命令行下运行分析模式 110
9.3.5 热点:分析程序哪里耗时 111
9.3.6 并行度:展现并行程序的另外一个特点 111
9.3.7 锁和等待:分析程序在哪里等待 112
9.3.8 选择数据采集的时段 112
9.4 Amplifier中浏览性能数据结果 112
9.4.1 总览 112
9.4.2 在Bottom-up和Top-down中切换 113
9.4.3 选择和管理栈类型 114
9.4.4 选择颜色方案 114
9.4.5 按照不同类型划分组 114
9.4.6 在命令行模式下查看性能数据 114
9.5 Amplifier解释性能数据结果 115
9.5.1 总览 115
9.5.2 解释热点分析结果 115
9.5.3 解释并行度分析结果 116
9.5.4 解释锁和等待分析结果 116
9.6 Amplifier中的源代码 117
9.7 Amplifier中对比性能数据结果 117
9.8 Amplifier中管理结果文件 119
9.9 小结 120
第10章 性能优化方法 121
10.1 性能优化概述 121
10.1.1 性能和性能优化是计算机领域不变的主题 121
10.1.2 性能优化的定义 121
10.2 性能优化通用方法 122
10.2.1 性能优化的顺序 122
10.2.2 系统级别的性能优化 122
10.2.3 应用级别的性能优化 123
10.2.4 微架构级别的性能优化 123
10.2.5 性能优化工作循环 123
10.2.6 性能优化循环的常见问题 123
10.3 并行应用性能优化方法 125
10.3.1 概述 125
10.3.2 减少关键路径上的时间 126
10.3.3 检查是否选择最优的并行方法 126
10.3.4 检查是否选择合适的层级开始并行 127
10.3.5 Amdahl定律的检查:减少串行部分的比例 127
10.3.6 检查程序的负载均衡问题 127
10.3.7 检查程序的粒度问题 128
10.3.8 采用合适的线程库 128
10.3.9 检查同步性能问题 129
10.3.10 检查硬件导致的扩展性问题 130
10.4 小结 130
第11章 性能优化案例 131
11.1 IO并行:系统级优化案例 131
11.2 锁的实现:锁优化案例 133
11.3 同步与负载均衡:生产消费类型的优化案例 134
11.4 优化临界区:WinThread循环计算型优化案例 144
11.5 负载均衡与归约:OpenMP循环计算型优化案例 148
11.6 线程数,桶数与锁:Hash表与TBB优化案例 153
11.7 选择合适的层级并行:任务与数据并行优化案例 164
11.8 避免硬件性能瓶颈:内存与高速缓存优化案例 165
11.9 算法选择:排序优化与TBB案例 168
11.10 内存操作TBB优化案例 172
11.11 小结 174
第12章 英特尔Parallel Advisor详解 175
12.1 Advisor基础 175
12.1.1 Advisor总览 175
12.1.2 如何开始Advisor 175
12.2 Advisor工作流程 177
12.3 Annotations 178
12.4 Advisor工具 179
12.4.1 Survey 179
12.4.2 Suitability 180
12.4.3 Correctness 181
12.5 使用案例 183
12.5.1 SpMV并行化 183
12.5.2 DGEMM并行化 188
12.6 小结 194
第13章 总体系统化案例 195
13.1 数独 195
13.1.1 串行算法 196
13.1.2 并行优化 211
13.1.3 小结 212
13.2 最短路径 213
13.2.1 串行算法 213
13.2.2 并行优化 232
13.2.3 小结 235
13.3 基数排序 236
13.3.1 串行算法 237
13.3.2 并行优化 245
13.3.3 小结 247
13.4 骑士巡游 248
13.4.1 串行算法 249
13.4.2 并行优化 265
13.4.3 小结 271
13.5 商业软件Paraview 271
13.5.1 问题描述 272
13.5.2 并行优化 272
13.5.3 小结 284
附录A 英文术语表 285