1.并行编程(1)并行程序的逻辑:1)将当前问题划分为多个子任务
2)考虑任务间所需要的通信通道
3)将任务聚合成复合任务
4)将复合任务分配到核上
(2)共享内存编程:
- 路障 ----> 条件变量,互斥量+忙等待(浪费cpu周期,重置) , 信号量(多个路障产生竞争条件)
- 临界区(更新共享资源的代码段)------>忙等待(标识变量),互斥量,信号量(信号量没有个体拥有权),读写锁
- 共享内存带来的问题:缓存一致性,线程的安全性 , 多个线程尝试更新一个共享变量的时候会产生问题(竞争条件)
- 线程是否越多越好:否,由于线程的切换和可能导致的二义性 。
- 线程和进程:线程是轻量级的进程 , 由进程派生,共享进程的大部分资源,但拥有独立的程序计数器和函数调用栈
- 局部性原理
- 空间局部性
- 时间局部性
- 空间局部性
- 串行部分决定了加速比的上限
- 矩阵加减
template <class T>T** add_sub(int n1,int m1,int n2,int m2,T **a,T *bb,int flag){T c[n1+10][m1+10];if(n1!=n2||m1!=m2){ cout<<"No Solution";return 0; }for(int i=1;i<=n1;i++)for(int t=1;t<=m1;t++)c[i][t]=a[i][t]+b[i][t]*flag;}
- 矩阵乘法
template <class T>T** mul(int n1,int m1,int n2,int m2,T **a,T **b){ if(m1!=n2){ cout<<"No Solution";return 0; }T c[n1+10][m2+10];for(int i=1;i<=n1;i++)for(int t=1;t<=m2;t++)c[i][t]=0;for(int i=1;i<=n1;i++)for(int t=1;t<=m1;t++){for(int j=1;j<=m2;j++){c[i][j]+=a[i][t]*b[t][j];}}}
- 矩阵除法
template <class T>T** div(int n1,int m1,int n2,int m2,T **a,T **b){T e[n1+10][n2+10];for(int i=1;i<=n2;i++){for(int t=1;t<=n2;t++){if(i==t) e[i][t]=1;else e[i][t]=0;}}//Gauss-Jordan消元法求矩阵的逆for(int i=1;i<=n2;i++){int max=i;for(int t=i+1;t<=n2;t++)if(fabs(a[t][i])>fabs(a[max][i])) max=t;if(fabs(a[max][i])<1e-10){cout<<"No Solution";return 0;}if(i!=max){swap(a[i],a[max]);swap(e[i],e[max]);}for(int t=1;t<=n2;t++){if(t!=i){double flag=a[i][i]/a[t][i];for(int j=1;j<=n2;j++){a[t][j]=flag*a[t][j]-a[i][j];e[t][j]=flag*e[t][j]-e[i][j];}}}}for(int i=1;i<=n2;i++){printf("%.2lf\n",a[i][n2+1]/a[i][i]);}return mul(n1,m1,n2,m2,a,e);}
(2)矩阵乘法优化文章插图
优化方法
- 矩阵分块(减少cache的缺失由于缓存容量的有限性)
- 矩阵的转置(空间局部性原理)
- 指令集向量化:avx256
- 多线程:pthread
`for(int i=1;i<N;i++)for(int t=1+i;t<N;t++)swap(b[i][t],b[t][i]);N--;thread_count=strtol(argv[1],NULL,10);thread_count=10;flag=(N+thread_count-1)/thread_count;pthread_t *threads;threads=(pthread_t*)malloc(thread_count * sizeof(pthread_t));for(int i=0;i<thread_count;i++){int* id = (int*)malloc(sizeof(int));*id = i;pthread_create(&threads[i],NULL,matrixMul,(void* )id);}for(int i=0;i<thread_count;i++)pthread_join(threads[i],NULL);free(threads);`?`void *matrixMul(void *rank){__m256d a1,b1;__m256d z= _mm256_setzero_pd();int my_rank=*((int*)rank);int T=128;for(int l=1+flag*my_rank;l<=min(N,flag*(my_rank+1));l+=T)for(int r=1;r<=N;r+=T)for(int k=1;k<=N;k+=T)for(int i=l;i<=min(l+T-1,flag*(my_rank+1));i++){for(int j=r;j<=min(r+T-1,N);j++){for(int t=k;t<=min(k+T-1,N/4*4);t+=4){a1=_mm256_loadu_pd(&a[i][t]);b1=_mm256_loadu_pd(&b[j][t]);a1=_mm256_mul_pd(a1,b1);c[i][j]+=a1[3]+a1[2]+a1[1]+a1[0];}}}for(int i=1+flag*my_rank;i<=min(N,flag*(my_rank+1));i++)for(int j=1;j<=N;j++){for(int t=N/4*4+1;t<=N;t++){c[i][j]+=a[i][t]*b[j][t];}}}`
3.HPL测试- 查看本机cpu为 12th Gen Intel Core tm i5-12500H 支持的指令集拓展为sse4.1,sse4.2,avx2
AVX2的处理器的单指令的长度是256bit,每颗intelCPU包含2个FMA,一个FMA一个时钟周期可以进行2次乘或者加的运算,那么这个处理器在1个核心1个时钟周期可以执行256bit推荐阅读
- 应用程序的并行配置不准确 应用程序并行配置不正确怎么办
- 并行配置不正确怎么办 并行配置不准确
- 书房用英语怎么说 书房用英语怎么说study
- 怎么用iPad看片 怎么用?ipad看片
- 文件并行配置不正确怎么办 解决并行错误的方法
- 书房英语怎么读 书房英语怎么读study