MIC C编程(offload模式)

MIC C编程(offload模式)

编程特点

简单---隐藏大量细节,语法与OpenMPI类似(不需要开辟空间)

灵活---OpenMP MPI(但是用的不多)pThread等多种方式

传统---与CPU编程一脉相承

MIC C扩展语言结构

编译指导方式(#pragma)

offload

--表示之后的代码段将使用offload模式运行

运行在其他设备上(MIC)

--标识内存传递参数,传递过程对用户透明

不需要手动写代码控制何时传入、何时传出

不需要手动申请卡上内存空间

不需要讲卡上内存与主机端内存空间手动对应

简单示例

#pragma offload target(mic)

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

{

printf(“Index:%d\n”,i);

}

循环和printf语句在MIC上执行,没有数据传输

此时循环是串行的,因为没有并行引语

offload语法

#pragma offload specifier[,specifier...]


specifier


示例


含义


target


target(mic:0)


使用什么设备运行


if


if(N>1000)


是否使用该设备


in


in(p:length(LEN) alloc_if(1))


数据传入device


out


out(p:length(LEN))


数据从device传出


inout


inout(p:length(LEN) align(8))


数据既传入又传出


nocopy


nocopy(p)


只开辟空间不传递


signal


signal(tag)


发送信号


wait


wait(tag1,tag2)


等待信号


mandatory


mandatory


必须用MIC运行

其中in/out/inout/nocopy可用的属性有


属性


示例


含义


length


length(LEN)


元素个数


alloc_if


alloc_if(1)


是否开辟内存


free_if


free_if(N>0)


offload后是否释放


align


align(8)


对齐


alloc


alloc(p[10:100])


开辟数组一部分


into


into(p[10:100])


传递数组一部分

语法详解target

#pragma offload target(mic)  mic这里目前只支持MIC卡

--这是必须使用的属性

--表示下面的代码段使用MIC运行

--现阶段,target的参数只支持“mic”

--使用哪块卡,由驱动决定,如果系统没有MIC卡,则使用CPU运行
target(mic:num)

--num>=-1;当为-1时,系统自动选择一块mic卡,如果1号卡不存在或者有故障,则程序报错退出

--设备号=num%mic数量(也就是说num可以大于mic卡数,循环的)

语法详解in

#pragma offload target(mic) in(array)  --传入CPU中的array,不负责传出

--可选属性

--可附加length、alloc_if、free_if、align、alloc、into属性

--表示进入offload区域时,将数组array从CPU内存中传递到MIC内存中,只传入不传出

--只需要传递数组,标量会自动以inout方式传递

语法详解out/inout/nocopy

可选属性

与in基本相似

out表示离开offload区域时,将数组array从MIC内存传递到CPU内存,只传出不传入

inout表示进入offload区域时,将数组从CPU内存传输到MIC内存,离开时将数组传回

nocopy表示仅开辟或保留空间,不传输数据

注意事项:

array是静态声明时,不用加长度参数

array是动态开辟时(堆),需要加长度参数length

array长度相同,或静态声明时,可以在一个传输区域内传输多个。例:in(a,b)

默认进入offload时开辟内存,离开时释放

in/out/inout/nocopy在一句offload中可以出现多次,但每个数组名只能出现一次

传输属性详解length

传输数组的元素个数,非数组长度!

只能使用在动态开辟的数组中

数组长度相同时可以共用

示例:

float *pArray,*pArray1;

pArray=(float*)malloc(LEN*sizeof(float));

pArray1=(float*)malloc(LEN*sizeof(float));

#pragma offload target \

in(pArray,pArray1:length(LEN))   共用啦

{……}

传输属性详解alloc_if,free_if

控制是否在传输前开辟卡上内存空间和传完是否释放

常结合nocopy属性应用

例:

#pragma offload target \

in(pArray:length(LEN) free_if(0))  里面是boolean型,“0”表示不释放空间

//进入下一个offload时,pArray的数据仍然存在(计算完后pArray存在于MIC中,不需要再从CPU端传输多MIC端了)

#pragma offload target \

nocopy(pArray:length(LEN) alloc_if(0)) 不用再释放空间了,也不用in再次传输了

//此时不需要开辟空间,否则会覆盖原有数据

(这里优化点:1:传输 2:开辟 3:释放)

数据传输优化Nocopy

p_c=...//p_c在每次迭代中值不变

for(i=0;i<steps;i++) //迭代次数

{

p_in=...;//每次迭代计算时,p_in的值变化

#pragma offload target(mic) \

in(p_in:length(...)) in(p_c:length(...)) out(p_out:lenth(...))

{

kernel(p_in,p_c,p_out);

}

}

...=p_out;//CPU端在所有迭代完成之后才用到p_out的值

这里的冗余是p_c冗余传入p_out冗余输出

优化方案:

p_c=...;//p_c在每次迭代中值不改变

#pragma offload target(mic) \

in(p_c:length(...) alloc_if(1) free_if(0)) \  //开辟不释放

nocopy(p_in:length(...) alloc_if(1) free_if(0)) \

nocopy(p_out:length(...) alloc_if(1) free_if(0))

{

}//申请空间,并且不释放,传递p_c的值

for(i=0;i<steps;i++){//迭代多次

p_in=...;

#pragma offload target(mic) \

in(p_in:length(...) alloc_if(0) free_if(0)) \   //p_in省去了steps次的开辟释放空间

nocopy(p_c) nocopy(p_out)   //这里p_c省去了输入,p_out省去了输出

{

kernel(p_in,p_c,p_out);

}}

//以下是把最后的p_out输出来

#pragma offload target(mic) \

nocopy(p_c:length(...) alloc_if(0) free_if(1)) \

nocopy(p_in:length(...) alloc_if(0) free_if(1)) \

out(p_out:length(...) alloc_if(0) free_if(1))

{...}

...=p_out

传输属性详解align

控制卡上内存开辟的对齐大小

单位为字节

内存不对齐时会影响性能

一般用于传输不规则的结构体(定义顺序)

传输属性详解alloc/into

alloc开辟卡上内存,大小为数组的一部分

into传输数据,大小为数组的一部分

不能与inout/nocopy同用

传输属性特殊用法

#pragma offload target \

in(p[10:100]:alloc(p[5:1000]))

在设备开辟了1000个元素的数组p,数组下表的可用范围是从5开始,即5-10004.然后将主机端从p[10]开始的100个元素传到设备端的p[10]-p[109]的位置(mic卡上)

需要程序员保证不会越界

#pragma offload ... \

in(p[0:500]:into(p1[500:500]))

将主机端p[0]开始的500个元素的值,复制到设备端p1[500]-p1[999]的响应位置

如果同一offload语句有多个into,执行顺序未知,因此需要注意目的数组范围不能重叠

into不是简单拷贝,维度不同不能传输

语法详解signal/wait

#pragma offload target(mic) signal(tag)

可选属性,异步传输

等同于offload_transfer/offload_wait,但后者为单一语句,后面不跟代码段

在传输语句时加signal,CPU不等待MIC运行结束即继续运行。知道遇到wait语句

wait语句等待signal语句传输完成再继续运行

参数为一个变量或者数组名(即使同事传递多个)

示例:

float *in1;

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

{

mic_compute();

}

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

#pragma offload_wait target(mic:0) wait(in1)  //这里与MIC合流

offload+OpenMP

在offload语句作用范围内使用OpenMp,即可在MIC上并行计算

例:

#pragma offload target(mic) out(arr:length(LEN))

#pragma omp parallel for

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

{

arr[i]=i*3.0/x;

}

变量和函数声明

_declspec(target(mic))

_attribute_((target(mic)))

修饰后,变量和函数可同时用于CPU和MIC,二者等价,attribute时注意有两层括号

例:

_attribute_((target(mic))) int a;

-attribute_((target(mic))) void fun();

变量和函数声明(批量)

同时声明多个变量和函数

两种形式

#pragma offload_attribute(push,target(mic))

//函数或变量声明

#pragma offload_attribute(pop)

或者:

#pragma offload_attribute(target(mic))

//函数或变量声明

#pragma offload_attribute(target(none))

判断代码段是否运行在MIC上

检查是否定义了宏_MIC_

#ifdef_MIC_

...

#else

...

#endif

需要封装在函数中,而不能直接用于offload代码段

_attribute_((target(mic))) void offload_check(void)

{

#ifdef _MIC_

printf(“check func:Run on the mic!\n”);

#else

printf(“check func:Run on the cpu!\n”);

#endif

}

语法详解if

#pragma offload target(mic) if(flag)  //flag 是boolean型的

可选属性

如果flag为真,则使用MIC执行代码段,否则使用CPU执行

例:#pragma offload target(mic) if(N>100)

表示如果N大于100就在MIC卡上执行

可用于不同规模数据,或者CPU、MIC协同计算的情况

语法详解mandatory

可选属性

没有参数

强制下面的代码段在MIC上运行,如果MIC设备不可用,则报错退出--不去CPU上跑

多用于必须在MIC上运行的代码,例如使用SIMD写的代码段

程序编译

使用Intel编译器

编译选项与原CPU程序完全一样

如果只想使用CPU,添加选项”-no-offload”

如果使用了OpenMP,添加选项”-openmp” (如果不加此选项,就在mic的单核上运行)

时间: 2024-10-02 19:35:54

MIC C编程(offload模式)的相关文章

简介Intel MIC上的分布式开发以及Offload模式下的各种限制

最近要在MIC机群上做分布式开发,发现有两种模式可以用: 1) offload模式:该模式和GPGPU编程思想类似,把并行度高的代码转移到local的MIC处理器上执行,其它代码仍然在CPU上执行.MIC只负责本地计算,分布式通信必须在CPU上执行. 2)symmetric模式:编译出在MIC和CPU上执行的两份二进制代码.该模式逻辑上允许MIC进行分布式通信,虽然物理上消息还是从CPU走的.这种模式编程最大的难点是load balancing问题. 通过几天探索,发现了offload模式下的各

简单实现异步编程promise模式

本篇文章主要介绍了异步编程promise模式的简单实现,并对每一步进行了分析,需要的朋友可以参考下 异步编程 javascript异步编程, web2.0时代比较热门的编程方式,我们平时码的时候也或多或少用到,最典型的就是异步ajax,发送异步请求,绑定回调函数,请求响应之后调用指定的 回调函数,没有阻塞其他代码的执行.还有像setTimeout方法同样也是异步执行回调的方法. 如果对异步编程还不太熟悉的话,直接戳 阮一峰大牛的教程 ,这篇文章介绍了四种异步编程的方式: 回调函数 事件监听 发布

it编程开发模式有哪些(二)

IT编程的开发模式一共有10种,或许有更多,但是常见的和常用的是10种模式.前面有提到了也详细的说明了前五种的开发模式,下面就来渐渐后面的五种开发模式.IT编程开发模式有哪些(二) 1. it编程开发模式 (1)边做边改模型(Build-and-Fix Model); (2)瀑布模型(Waterfall Model); (3)快速原型模型(Rapid Prototype Model); (4)增量模型(演化模型)(Incremental Model); (5)螺旋模型(Spiral Model)

介绍MVC编程架构模式

MVC(Model/View/Controller)模式是国外用得比较多的一种框架模式,最早是在Smaltalk中出现.MVC包括三类对象. Model——是应用对象 View——是它在屏幕上的表示 Controller——定义用户界面对用户输入的响应方式. 模型-视图-控制器(MVC)是80年代Smalltalk-80出现的一种软件框架模式,现在已经被广泛的使用. 1.模型(Model) 模型是应用程序的主体部分.模型表示业务数据,或者业务逻辑. 2.视图(View) 视图是应用程序中用户界面

异步编程的模式

一.回调函数 function f1(callback){ setTimeout(function () { // f1的任务代码 callback(); }, 1000); } f1(f2); 优点是简单.容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),使得程序结构混乱.流程难以追踪(尤其是回调函数嵌套的情况),而且每个任务只能指定一个回调函数. 简单,难维护,高耦合 二.事件监听 事件驱动模式.任务的执行不取决于代码的顺序,而取决于某个事件是否发生 f

Android.mk(4) 依赖:目标编程的模式

https://www.jianshu.com/p/3777a585a8d0 另一种范式 我一直觉得,Makefile确实是C/C++程序员的良配,因为Makefile所使用的两种范式都是C/C++程序员不熟悉的,一种是函数式的思想,一种是依赖构成的目标链的模式. Makefile从最基本上来说,可以抽象成下面这样的: target ... : prerequisites ... command ... ... 如大家所熟悉的,这段的意义是:当prerequisites有更新的时候,执行comm

面向对象编程中设计模式学习笔记

上学期学的OOP,最近把期末复习笔记拿出来温习,共享一发. Polymorphism means many different form If you have inheritance, you have polymorphism Inheritance Polymorphism Abstraction Encapsulation Information hiding Loose coupling Hello.exe (an executable) Hello.dll (an assembly

11-13 游戏编程行为模式

### Behavioral Pattern #### interpreter pattern string -> code instruction set: 提供基本操作 virtual machine: 执行指令 front-end: 生成效率更高的字节码 ``` void setHealth(int wizard, int amount); void setWisdom(int wizard, int amount); void setAgility(int wizard, int amo

MIC简介

一:MIC是什么? (一)MIC是架构名称-Intel Many Integrated Core(Intel集成众核) (二)众核协处理器(Co-Processor) --通过PCIE与CPU通信 --众核.重核 (三)基于x86架构和x86指令集 二:MIC特性 MIC卡: 最高61 cores 主频1.2GHz 244 Threads 但是最多能开240个线程,有4个线程跑OS 最高内存容量16GB,内存带宽352GB/s 单卡双精度峰值性能>1.2TFLOPS MIC Core的组成 X8