并行运算学习笔记

本文探讨了并行与并发的概念,包括MIMD、SIMD等并行模型,强调了共享内存和分布式内存系统的特点。还讨论了并行计算中的竞争条件、互斥锁和临界区,并介绍了加速比、并行程序效率和可扩展性。此外,文章提到了MPI和OpenMP等并行编程工具,以及如何通过循环合并、循环展开等技术优化程序性能。并行化开销和GPU与CPU的区别也是讨论的重点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

三.
并行:表面并行,不断切换。并发:真正的并发操作


mimd 多指令多数据。(sisd,simd,misd )
simd在并行性较大的数据问题上游泳,但对复杂的并行问题帮助不大。
mimd系统通常是异步的。
共享内存系统,分布是式存系统。
共享内存系统:一组自治的处理器通过互联网与内存系统相互连接,每个处理器能够访问每个内存区域。(cpu)
分布是内存系统:每个处理器有自己的私有内存,处理器之间通过发送消息或者使用特殊的函数访问其他处理器内存。(socket)




四.
1.printf("thread %d ->my_value = %d \n" , my_rank. my_x)
竞争问题,即读写冲突。称之为非确定性。
当进程或线程尝试同时访问一个资源时,称程序有竞争条件。
临界区:一次只能被一个线程所执行的代码块。
互斥锁:由硬件支持的一个特殊类型的对象。
MY_VALUE = COMPUTE_VAL(MY_RANK);
LOCK (&ADD_MY_VALUE_LOCK);//忙等待,一个县城进入循环,只为了测试一个条件
//操作
UNLOCK(&ADD_MY_VALUE_LOCK);
//锁加太多会影响时间效率,性能,尽量不要多加(使得并行变成了穿行)
加速比s=T串行/T并行
必须穿行执行的计算a
可以并行执行的计算b
并行开销c(冗余计算和通信操作)
串行执行时间T1=a+b
并行执行时间T2=a+b/p+c(p个处理器)
并行程序效率:E=T1/(T2*P)


GUSTAFSON-BARSIS 加速比<=p+(1-s)p,s表示并行总执行时间中串行代码的比例
amdahl从串行角度出发,由你出发,问题规模角度(串行总执行中串行代码的比例)
增加并行程序使用的进程或者线程数,如果问题规模也以相应的增长率增加,该程序的效率值e保持不变,则称该程序是可扩展的。
增加线程进程数,不增加问题的规模,仍然可以位置固定的效率e,则强可扩展
增加线程进程数,增加相同倍率的问题规模,效率e不变,则弱可扩展


五.
计时:开发过程中分析实现或设计中的问题;运行时的性能,
如何计时:所有线程同时开始计时,取最长的线程时间作为总进程并行执行时间。一般不将io时间记录在内(多次运行时间不同取最短运行时间)
一般线程数与cpu内核数正比关系
任务指的是一个程序其本地存储以及一组io端口
通道是连接一个任务的输入与输出端的消息队列
任务/通道模型发送信息异步接受信息同步
lan foster并行算法设计过程:划分.通信.聚集.映射(将聚集成的大任务分派到内核上)(通常划分决定并行计算进行的上限,聚集为了减少new,delete开销)
划分质量评估:划分任务数高于处理器数一个数量级,荣誉计算最小化,任务大概相同,任务数是问题规模的增函数
通信结构评估:平衡的人物同心,每个任务仅与少量邻居通信,任务能并发执行通信、计算(通信和计算同时进行为最好)
聚集原则:通常聚集无法并发执行的任务,能减少消息发送的数目
映射分类:固定映射,动态负载均衡算法(集中式与分布式,一般选分布式)
mpi:


mpi初始化:例如信息缓冲区的分配
int MPI_iNIT{
InT * ARGC_P;
CHAR *** ARGV_P};


Mpi结束要用Mpi_Finalize();


通信子指的是一组可以互相发送信息的进程集合,通信子的集合也成为通信域。
缺省通信子MPI_COMMM_WORLD


MPI_Comm_size进程数。
第一个参数通信域,第二个int形进程数量指针


MPI_Comm_rank进程序号。
第一个参数通信域,第二个int形进程序列指针


int_Mpi_Send(
void* msg_buf_p          消息指针
int msgsize 消息大小 (接收为缓存容量,发送未发送信息大小)
MPI_Datetype 消息类型(已定义有诸如int float之类包括struct)
int dst 接收消息进程号
int tag 识别标签,用来区别看上去完全一样的消息
MPI_Comm communicator 发送接收进程所在的通信域
)


接受与发送数据类型相同,只多一个MPI_Status* status_p表示接受状态,是否成功或者失败,成功的信息以及错误的信息。
  





any source any tag 以接受多个信息
有一个函数专门返回接收信息的进程号









文档识别分类
1读取字典
2标识文档
3读取并分析文档
4保存向量
1.2可进行任务并行
 mpi_Comm_spkit(                //通信域的划分
Mpi_Comm comm, //原通信域
int color      // 相同的通信域属于一个颜色
int key        //划分后的通信域内的进程序号(如果color相同,key相同,则按原通信域中进程号排序)
Mpi_Comm*    new_comm    //新通信域

非阻塞式比原recv多一个Mpi_Request * handle




派生类数据类型
(数据类型,偏移量)ps构成了空间









(ps取余操作与除数操作耗费cpu都很大,可以用移位来替代)
排序算法
奇偶交换排序
偶数阶段:(a0,a1)(a2,a3)....
奇数阶段:(a1,a2)(a3,a4)....
最差排序次数为排序个数


九 用pthreads进行共享内存编程
./pth_hello<number of thread>   run pthread
mpiexec -n <number of process>  run mpi
 
int pthread_creat(
pthread_t* thread_p  //调用前必须分配内存空间
const pthread_attr_t* //大多数情况下该参数赋值空,除非需要修改线程的缺省属性
void* //*start routine(void*) 即新生成的线程启动后要运行的函数
void*}// 为第三个函数进行参数传递,在上面的void*(通常为每一个线程传送一个int形的参数rank表示线程的序号)
调用一次创建一个线程


pthread——join(
pthread_t           thread,//(非指针)
void**                     //线程关联参数的返回值





随着n问题规模增加,双线程计算结果越来越糟,如果同时修改赋值给一个共享变量(竞争共享变量)
互斥量是互斥锁的简称,pthread_mutex_t (init,destroy)(pthread_mutex_lock,unlock)
1.互斥量肯定是共享的,声明共享
2.main函数中init初始化。
3.多个线程访问时使用互斥量对象控制临界区资源,
4.main在最后释放







 
十一
(openmp)parallel for()指令(适用于任何for循环之中)
pragma omp parallel for num_threads(count)\
reduction(+:approx)  //共享变量
private (factor) //将factor为每个线程建立私有变量副本
firstprivate(x) //希望尽然parallel块后,各个线程内能够获得变量在主线程的初始值
lastprivate(x) //最后可以将线程内的私有变量值传给主进程
1.(使用条件限制:1使用了while,2不能确定循环次数3有break(循环多于一个出口,就是不能确定迭代次数))
2.注意事项:1循环期间i++的i只能被for语句中的增变量表达。2结束条件或者不能再循环执行期间改变。3i必须是指针或者整形。
3.关于迭代一般也不能使用parallel for .
4.数据依赖关系:读后读无影响,读后写不能并行执行,但可以通过变量名重命名机制实现,写后读严格串行不能并行,写后写也可使用重命名
机制消除依赖关系。
5.主线程中声明的变量在parallel中默认作用域为共有的,在fefault(none)后使用private and shared将变量定义为私有作用域和共享作用域
一般只读的就可以写道shared后面
6.奇偶交换在p阶段和p+1
阶段会存在循环依赖,所以要设置隐含的障碍,使得p阶段都完成后再进行p+1阶段
7.将parallel for拆成了 parallel和for两部分。
可以提钱生成线程数量,然后在使用时加入praga   ,指令从而使得不会反复开线程关线程,从而提升性能。



十三.
程序性能优化方法:系统级应用级,算法级别,循环级别,语句级别

1循环合并,判断次数减小,利于寄存器缓存,更容易增加流水线的执行性能
2循环展开:由于展开能够消除分支以及一些管理归纳变量的代码,因此可以摊销一些分支开销。展开过度或展
开非常大的循环时,可能导致代码篇幅增加。如果展开后的循环不能再放入跟踪缓存 (TC),这将有害无益。
3循环累计:和循环展开同时使用,在减少寄存器使用量的同时,保存并行度
4循环拆分:寄存器cache能够完全存储进去

注意循环依赖尤其写后读(写后读通常将要写的值赋给x即一个寄存器,再通过寄存器将值赋给原变量,读时读取寄存器,避免写后读)
指令级别(减少数据分支)




十四.
s=['D','D','C','B','A'];
return s[score/10];




并行化开销:1初始化多线程数据结构2设置路障,快等慢3通信操作,归约合并程序结果
并行化开销随着线程数增加而增加,随着chunksize增大而减少


可以通过nowait消除parallel for设置的隐含的路障(任何路障都行)
格式:#parallel omp nowait
程序性能优化方法,最大化并兴趣与,增大并行区域范围,减少并行数量。




GPUvs CPU
cpi为串行程序的高效执行进行了大量的优化
gpu专为打大量数据的并行执行设计
 线程网格由线程块组成,线程块有线程 组成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值