MIC性能优化

MIC优化方法:

--并行度优化

--内存管理优化

--数据传输优化

--存储器访问优化

--向量化优化

--负载均衡优化

--MIC线程扩展性优化

一:并行度优化

要保证有足够的并行度,效果才能好(数据并行,任务并行)

优化步骤:

1.写OpenMP程序

2.测试他的扩展性,比如用两个测试,然后4个,6个,8个线程测试

3.然后移植到MIC上面

MIC优化准则:外层并行,内层向量化

示例一:

for(i=0;i<M;i++)

{

for(j=0;j<N;j++){

......

}

}

两种并行模式:

其一:

#pragma omp parallel for num_threads(THREAD_NUM)   //开启了M次

for(i=0;i<M;i++){

for(j=0;j<N;j++)

{......}

}

其二:

#pragma omp parallel num_threads(THREAD_NUM)

for(i=0;i<M;i++){

#pragma omp for                                 //开启了M*N次,开销较大

for(j=0;j<N;j++)

{......}

}

示例二(嵌套并行):

for(i=0;i<M;i++)

{

for(j=0;j<N;j++)              //问题:每层循环次数太少,不能很好的发挥MIC卡的作用

{......}

}

可以改变成如下两种形式:

其一:

#pragma omp parallel for num_threads(THREAD_NUM)

for(k=0;k<M*N;k++){

i=k/M;

j=k%M;

}

其二:

omp_set_nested(true); //声明允许嵌套并行

#pragma omp parallel for num_threads(THREAD_NUM1)

for(i=0;i<M;i++){

#pragma omp parallel for num_threads(THREAD_NUM2)

for(j=0;j<N;j++){......}

}

二:内存管理优化

MIC内存大小:6GB~16GB

分块处理:例如程序需要28GB,假设MIC卡每次可以使用的内存为7GB,那么需要分4次计算

改变并行层次:

--并行内层循环

外层循环-->内层循环(线程间数据共享)

--任务级并行-->数据级并行

减少申请次数

关键:开辟空间操作放在循环之外

三:数据传输优化:Nocopy(参见上一节《MIC C编程》)

异步传输:MIC在做的时候CPU也可以做

示例:

#pragma offload_transfer target(mic:0) in(in1:length(count) alloc_if(0) free_if(0)) signal(in1)

for(i=0;i<iter;i++)

{

if(i%2==0){

#pragma offload target(mic:0) nocopy(in1) wait(in1) out(out1:length(count) alloc_if(0) free_if(0))

compute(in1,out1);}

else{

#pragma offload_transfer target(mic:0) if(i!=iter-1) in(in1:length(count) alloc_if(0) free_if(0)) signal(in1)

#pragma offload target(mic:0) nocopy(in2) wait(in2) out(out2:length(count) alloc_if(0) free_if(0))

compute(in2,out2);

}

}

异步计算:CPU与MIC异步,计算和I/O异步

int counter;

float *in1;

counter=10000;

_attributes_((target(mic))) mic_compute;

while(counter>0)

{

#pragma offload target(mic:0) signal(in1)

{

mic_compute();

}

cpu_compute();  //此时本函数与上面的MIC函数并行执行

#pragma offload_wait target(mic:0) wait(in)

counter--;

}

SCIF(VS offload)

擅长小数据传输

如果传输的数据是1K、2K、3K,那么SCIF/offload=80%

如果传输的数据>4K,两者效率差不多

如果传输的数据>6K,SCIF大幅度下降

五:存储器访问优化

MIC存储器访问优化策略

--隐藏存储器访问延迟

多线程

预取

--利用Cache优化

时间局部性

空间局部性

--对齐

Cache优化方法:

代码变换

--循环融合

--循环分割

--循环分块

--循环交换

数据交换

--数据放置

--数据重组

循环融合

//original loop;

for(i=0;i<n;i++)

a[i]=b[i]+1;

for(i=0;i<n;i++)

c[i]=a[i]/2;

融合:

//fused loop

for(i=0;i<n;i++)

{

a[i]=b[i]+1;

c[i]=a[i]/2;

}

循环分割:

//original loop

for(i=1;i<n;i++)

{

a[i]=a[i]+b[i-1];

b[i]=c[i-1]*x*y;

c[i]=1/b[i];

d[i]=sqrt(c[i]);

}

分割:

//splitted loop

for(i=1;i<n;i++)

{

b[i]=c[i-1]*x*y;

c[i]=1/b[i];

}

for(i=1;i<n;i++)

a[i]=a[i]+b[i-1];

for(i=1;i<n;i++)

d[i]=sqrt(c[i]);

循环分块:

//original loop

for(i=0;i<n;i++)

for(j=0;j<m;j++)

x[i][j]=y[i]+z[j];

分块:

//tiled loop

for(it=0;it<n;it+=nb)

for(jt=0;jt<m;jt+=mb)

for(i=it;i<min(it+nb,n);i++)

for(j=jt;jt<min(jt+mb,m);j++)

x[i][j]=y[i]+z[j];

循环交换:

//original loop

for(j=0;j<m;j++)

for(i=0;i<n;i++)

c[i][j]=a[i][j]+b[j][i];

一般用于矩阵运算,问题:访问不连续

//interchanged loop

for(i=0;i<n;i++)

for(j=0;j<m;j++)

c[i][j]=a[i][j]+b[i][j];

六:向量化优化(VPU进行批操作)

Intel自动向量化,512/32 处理16个单精度

自动向量化:

什么样的循环可以自动向量化?

1.编译器认为循环内的每条语句之间都没有依赖关系且没有循环依赖

2.最内层循环

3.数据类型尽量一致

一般不会自动向量化

1.for(int i=0;i<N;i++)

a[i]=a[i-1]+b[i];

2.for(int i=0;i<N;i++)

a[c[i]]=b[d[i]];

3.for(int i=0;i<N;i++)

a[i]=foo(b[i]);

4.迭代次数不确定

查看是否真的向量化了:

-qopt -report=[=n]


-qopt-report[n]


含义


n=0


不显示诊断信息


n=1


只显示已向量化的循环(默认值)


n=2


显示已向量化和未向量化的循环


n=3


显示已向量化和未向量化的循环以及数据依赖信息


n=4


只显示为向量化的循环


n=5


显示未向量化的循环以及数据依赖信息

引导向量化策略

插入引语自动向量化:不改变原程序结构,只需要插入预编译指令(引语)即可自动向量化。

调整程序循环结构并插入引语自动向量化:对源程序做一些结构调整,如嵌套循环交换次序等,然后插入引语可以自动向量化。

编写SIMD指令:SIMD指令可以比自动向量化获得更好地性能,但针对不同的硬件平台编写的SIMD指令也不同,并且SIMD指令易读性较差,所以SIMD指令可以选择性使用。

自动向量化:优势

提高性能:向量化处理,实现了单指令周期同时处理多批数据

编写单一版本的代码,减少使用汇编使编码工作简化:较少的汇编意味着会大大减少为特定的系统编程的工作,程序将很容易升级并使用于最新的主流系统而不必重新编写那些汇编代码。

#pragma ivdep      //建议向量化

#pragma simd      //强制向量化

C99 加-restrict

#pragma vector always  //如果引语不成功

指定循环向量化的方式,避免一些没有内存对其的操作没有被向量化

七:负载均衡优化

用于多节点多卡

集群多节点间并行框架

主函数:

#define N(10000)

_global_void kernel();

void main()

{

int calc_num,calc_len,rank,size;

MPI_Init(argc,argv);

MPI_Comm_size(MPI_COMM_WORLD,&size);//总节点数

MPI_Comm_rank(MPI_COMM_WORLD,&rank);//节点号

calc_num=......;calc_len=......;//计算运算的元素数

int *a=(int *)malloc(calc_len*sizeof(int));

if(rank==0) MPI_Send();//主节点分发数据

else MPI_Recv();//子节点接收数据

main_calc();

MPI::Finalize();   free(a);

return 0;

}

单节点多卡的编程框架

外围框架伪代码

int device_num=M+1;//M为单节点上GPU(MIC)卡的数目

omp_set_nested(true);//允许OpenMP嵌套

#pragma omp parallel for private(...),num_threads(device_num)   //卡与CPU同时计算

{for(i=0;i<device_num;i++)

{

if(i==0)

{

//CPU端计算

int j;

#pragma omp parallel for private(...)

for(int j=0;j<device_num;j++)

a[k]=k+6;

}

else{

MIC_kernel();

}

}

}

设备内负载均衡

通过调度算法(static、dynamic、guided等,已经学过,略过)

其余方法略。

时间: 2024-09-30 10:29:27

MIC性能优化的相关文章

MIC性能优化策略

MIC性能优化主要包括系统级和内核级:系统级优化包括节点之间,CPU与MIC之间的负载均衡优化:MIC内存空间优化:计算与IO并行优化:IO与IO并行优化:数据传递优化:网络性能优化:硬盘性能优化等.内核级优化包括并行度优化:负载均衡优化:进程/线程的同步优化:线程扩展优化:向量化优化:cache优化:数据对齐优化:库函数的选择等. 并行度优化 MIC上的并行化主要涉及并行线程/进程的数目,并行层级,并行粒度等方面. 并行度 MIC卡上包含众多的物理核,同时每个核上可以开启4个线程.例如一块60

iOS开发——项目实战总结&amp;UITableView性能优化与卡顿问题

UITableView性能优化与卡顿问题 1.最常用的就是cell的重用, 注册重用标识符 如果不重用cell时,每当一个cell显示到屏幕上时,就会重新创建一个新的cell 如果有很多数据的时候,就会堆积很多cell.如果重用cell,为cell创建一个ID 每当需要显示cell 的时候,都会先去缓冲池中寻找可循环利用的cell,如果没有再重新创建cell 2.避免cell的重新布局 cell的布局填充等操作 比较耗时,一般创建时就布局好 如可以将cell单独放到一个自定义类,初始化时就布局好

Java性能优化之JVM GC(垃圾回收机制)

Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行.当stop-the-world 发生时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成.GC优化很多时候就是减少stop-the-world 的发生. JVM GC回收哪个区域内的垃圾? 需要注意的是,JV

Spark性能优化指南——高级篇

Spark性能优化指南--高级篇 [TOC] 前言 继基础篇讲解了每个Spark开发人员都必须熟知的开发调优与资源调优之后,本文作为<Spark性能优化指南>的高级篇,将深入分析数据倾斜调优与shuffle调优,以解决更加棘手的性能问题. 数据倾斜调优 调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的性能. 数据倾斜发生时的现象 绝大多数tas

Mysql数据库性能优化(一)

参考 http://www.jb51.net/article/82254.htm 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库. mysql的性能优化无法一蹴而就,必须一步一步慢慢来,从各个方面

Android应用程序性能优化Tips

主要介绍一些小细节的优化技巧,虽然这些小技巧不能较大幅度的提升应用性能,但是恰当的运用这些小技巧并发生累积效应的时候,对于整个App的性能提升还是有不小作用的.通常来说,选择合适的算法与数据结构会是你首要考虑的因素,在这篇文章中不会涉及这方面的知识点.你应该使用这篇文章中的小技巧作为平时写代码的习惯,这样能够提升代码的效率. 通常来说,高效的代码需要满足下面两个原则: 不要做冗余的工作 尽量避免执行过多的内存分配操作 To ensure your app performs well across

使用Html5+C#+微信 开发移动端游戏详细教程:(六)游戏界面布局与性能优化

本篇教程我们主要讲解在游戏界面上的布局一般遵循哪些原则和一些性能优化的通用方法. 接着教程(五),我们通过Loading类一次性加载了全部图像素材,现在要把我们所用到的素材变成图片对象显示在界面上,由上而下,首先是top层,top里面包涵了玩家(微信)头像,关卡信息,怪物血条信息,玩家金币,玩家宝石,玩家总攻击力. 定义函数 setTop 来初始化top层: function setTop() { TopDiv = new LSprite();//定义top层 var Topshape = ne

电商邮件服务平台性能优化谈

从今年一月份开始,团队陆续完成了邮件服务的架构升级.新平台上线运行的过程中也发生了一系列的性能问题,即使很多看起来微不足道的点也会让整个系统运行得不是那么平稳,今天就将这段时间的问题以及解决方案统一整理下,希望能起到抛砖的作用,让读者在遇到类似问题的时候能多一个解决方案. 新平台上线后第一版架构如下: 这版架构上线后,我们遇到的第一个问题:数据库读写压力过大后影响整体服务稳定. 表现为: 1.数据库主库压力高,同时伴有大量的读,写操作. 2.远程服务接口性能不稳定,业务繁忙时数据库的插入操作延迟

web前端性能优化

前言:  在同样的网络环境下,两个同样能满足你的需求的网站,一个“Duang”的一下就加载出来了,一个纠结了半天才出来,你会选择哪个?研究表明:用户最满意的打开网页时间是2-5秒,如果等待超过10秒,99%的用户会关闭这个网页.也许这样讲,各位还不会有太多感触,接下来我列举一组数据:Google网站访问速度每慢400ms就导致用户搜索请 求下降0.59%;Amazon每增加100ms网站延迟将导致收入下降1%;雅虎如果有400ms延迟会导致流量下降5-9%.网站的加载速度严重影响了用户体验,也决