一.基于任务的程序设计
- 共享内存多核OS和分布式内存OS
共享内存多核OS-一个微处理器由多个内核组成,且每个内核共享一段私有内存;
分布式内存OS-- 由多个微处理器组成,每个微处理器可以有自己的私有内存,微处理器可以位于不同的计算机上,每个计算机可以有不同的通信信道
消息传递接口(MPI):运行在分布式内存计算机系统上的并行应用程序所使用的最流行的通信协议;
- 并行程序设计和多核程序设计
并行程序是指同一时刻运行多条指令,编写的代码能够充分利用底层硬件提供的并行执行能力;多核程序设计能够充分利用多个执行内核并行运行多个指令;
- 硬件线程和软件线程
物理内核(physical core)--真正独立的处理单元,多个物理内核使多条指令能够同时并行的运行。
每一个物理内核可提供多个硬件线程(亦称逻辑内核或逻辑处理器);
对称多线程(simultaneous multithreading,SMT):使用超线程计技术(HT)使微处理器在每个物理内核上提供多份架构状态,从而获得了 物理内核数X架构状态数 个硬件线程;
软件线程:每一个软件线程与其父进程分享一个私有的唯一的内存空间,但每一个软件线程有自己的栈、寄存器和私有局部存储区域;可以将硬件线程比作泳道,软件线程比作游泳者;
负载均衡:将软件线程的任务分发在多个硬件线程的操作,通过负载均衡,工作负载可以公平地分配在硬件线程之间。实现负载均衡取决于应用程序的并行程度、工作负载、软件线程数、可用的硬件线程以及负载均衡策略;
- Amdahl法则
预测多处理器系统的最大理论性能提升(加速比)
公式:最大加速比=1/((1-P)+(p/N))
P指能够完成并行运行的代码比例
N指可用的计算单元数(处理器或物理内核数)
- Gustafson法则
通过问题的大小来测量在固定时间内的可以执行的工作量;
总工作量(单元数)=S+(N*P);
S表示一次顺序执行完成的工作单元数;
P表示每一部分能够完全并行执行的工作单元数;
N表示可用的执行单元数(处理器数或物理内核数)
- 重量级并发模型和轻量级并发模型
重量级并发模型(多线程编程模型):编写复杂的多线程代码;将算法分解为多个线程、协调各个代码单元、在代码单元之间共享信息以及收集运算结果等任务;并且多线程模型过于复杂,难以应对多核革命;由于框架层次缺乏对多线程范围的支持,多线程需要做大量处理,这会导致代码复杂难以理解;
轻量级并发模型:减少了在不同逻辑内核上创建和执行代码所需要的总开销,并不只是关注不同逻辑内核之间的作业调度,还在框架级别添加对多线程访问的支持;
- 交错并发,并发和并行
交错并发:一次执行一个线程的指令,两个线程的指令交错执行
并发 :两个线程的指令同时执行
并行化要求:对需要完成的工作进行划分、并发的运行处理划分的部分、并且能够整合运行结果;对一个问题进行并行化就会产生并发性;
- 多核并行程序设计原则
按照并行的方式思考
使用抽象编程(TPL任务并行库)
按照任务(事情)编程,而不是按照线程(CPU内核)线程
设计的时候要考虑关闭并发的情形
避免使用锁
李永胜为帮助并发而设计的工具和库
使用可扩展的内存分配器
设计的时候要考虑增长的工作负载而扩展
CoreInfo --查看处理器信息程序
二. 命令式数据并行
TPL支持数据并行 任务并行 流水线(任务并行和数据并行的结合体)
Parallel.Invoke 对给定的独立任务提供潜在的并行执行;
需要传入一个要并行执行的Action的参数数组
方法没有特定的执行顺序,只有在所有方法都执行完之后才会返回;
Parallel.For 为固定数目的独立For循环迭代提供了负载均衡的潜在的并行执行;
循环并行化,不支持浮点数和步进。无法保证迭代执行的顺序;
Parallel.ForEach为固定数目的独立For循环迭代提供了负载均衡的潜在的并行执行;支持自定义分区器,让你可以完全掌控数据并发;提供了20种重载方法
利用一个范围整数作为一组数据,通过一个分区器,把数据分成一组数据块。每一块的数据都通过循环的方式处理,而这些循环都是并行的。
根据内核数目优化分区
Environment.ProcessorCount 获取逻辑内核的个数
从并行循环中退出
在参数中使用ParallelLoopState,就可以使用loopState.Break();或者loopState.Stop();进 行退出。其中的差别在于,假设调用Break的时候正在处理迭代100,那么可以保证小于100的迭代都被执行,而Stop不保证这个。
ParallelLoopResult作为返回值,可以知道是否是正常完成或者被Break的
捕获并行循环的异常
try
{
loopResult =
Parallel.ForEach(inputData,
(int number, ParallelLoopState
loopState) =>
{ throw new Exception(); });
}
catch (AggregateException ex)
{
foreach (Exception innerEx in ex.InnerExceptions)
{
Debug.WriteLine(innerEx.ToString());
}
}
ParallelOption
用于修改最大并行度。
var parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = maxDegree;
三.
命令式任务并行
System.Threading.Tasks.Task
一个Task表示一个异步操作,其创建和执行时独立的。
Task的状态和生命周期