MIC中的数据传输

先看一段代码,如下

 1 #include<stdlib.h>
 2 #include<stdio.h>
 3 #define LEN 5
 4 int main(int argc,char** argv){
 5     int i;
 6     float x=2;
 7     float arr[LEN];
 8     #pragma offload target(mic) out(arr)
 9     for(i=0;i<LEN;i++){
10         arr[i]=i*3.0f/x;
11     }
12     if(fabs(arr[2]-2*3.0f/x)<1e-6)
13         printf("Demo is right\n");
14     else
15         printf("Demo is wrong,arr[2] id %f\n",arr[2]);

符合首页要求,会被工作人员移出首页,望理解。如有疑问,请联系[email protected]。

网站分类


16     return 0;
17 }

out是出现的关键字,这个关键字的意思时告诉编译器,括号内的变量/数组是需要输出的。这样驱动就会自动的在代码离开离开MIC卡时,将变量内容拷贝到内存中的相应位置去。于此类似的还有,in,inout,nocopy关键字。

in:输入。在设备端开辟空间并将主机端数据复制到设备端。

out:输出。在设备端开辟空间,在进入设备端时将主机端数据复制到设备端,从设备端离开时,将数据从设备端复制到主机端。

nocopy:不拷贝,仅建立空间,不复制数据。

(1)传输关键字可以有零个或多个,当有多个时,可以连续书写,之间也可以用逗号或空格隔开。相同的传输关键字可以在一个offload语句中使用多次 ,但相同的变量名不可以在一个offload中出现啊多次(即使在不同关键字的参数中)。

(2)传输关键字后跟括号,括号内的参数是C/C++的变量名。

(3)变量应为数组名或指针(特指指向动态数组的指针)或普通变量(标量),多个变量之间用逗号隔开。

(4)变量为指针时,指针只能指向非指针变量,即不支持二维指针。

(5)变量为数组或指向数组的指针时,可以指定数组的起始和长度。

(6)变量为指针时,需要在变量名后加上“:length(len)”,不含引号,其中len为动态数组的元素个数,若多个动态数组元素个数相同,可写在一处,例如:in(a,b,c:length(20))。元素个数可以是变量。

(7)除了length以外,还有alloc_if,free_if,align,alloc,into等5个关键字,使用关键字之前也需要用冒号分隔(一个传输关键字可以用一个冒号即可)。

(8)alloc_if和free_if的参数时判断型表达式,其计算结果应是布尔型。如果alloc_if的参数结果为真则在进入设备端时为前述变量开辟空间,如果free_if的参数结果为真则在离开设备端时为前述变量释放空间(下有例子)。

(9)align的参数是一个正整数,其必须是2的整数次幂,其含义是:在设备端开辟的前述变量,以align参数的长度对齐。

(10)alloc的参数是变量或数组名,但只能一对一的传递,其含义是:将数组从主机端拷贝到设备端的另一个数组,或相反。into可以和alloc,alloc_if,free_if结合使用。但不能与inout,nocopy同时使用。

下面是一些代码片段

 1 //以下两行仅在设备端上开辟内存
 2 #pragma offload target(mic) nocopy(P:length(sz) alloc_if(1) free_if(0))
 3 {};
 4 //nocopy:不需要从主机端拷贝数据,代码段退出时不从设备端拷贝回主机端
 5 //p:(length(sz)): nocopy的是名为p的元素个数为sz(注意这里虽然关键字是length但不是数组长度,而是元素个数)的数组
 6 //p: 必须在主机端事先声明,可以仅声明一个指针而不必开辟空间,因为如果不声明的话,MIC端无法得知p的类型
 7 //alloc_if(1): 开辟内存
 8 //free_if(0): 代码段(本offload)退出时不释放内存
 9
10
11 //以下两行从主机端拷贝数据到设备端
12 #pragma offload in(p:length(sz) alloc_if(0) free_if(0))
13 {/*这里使用数组p进行运算*/}
14 //in: 从主机端拷贝数据到设备端
15 //因为p在上一个offload代码段已引用,且并没有释放内存,所以这里可以直接使用
16 //alloc_if(0): 不开辟内存。因为上段代码没有删除内存空间
17
18
19 //以下两行禁止任何改变p内存分配的操作
20 #pragma offload nocopy(p)
21 {/*这里使用p进行运算*/}
22 //没有显式指定,则不会有传入/传出/创建空间/删除空间的操作,且仅有这种用法时,无需指定数组长度
23
24
25 //以下两行将数据传出并释放内存
26 #pragma offload out(p:length(sz) alloc_if(0) free_if(1))
27 {/*这里使用p进行运算*/}
28 //out:退出时将数据从设备端拷贝到主机端
29 //alloc_if(0): 不创建内存空间(因为前面没有释放)
30 //free_if(1): 退出时释放空间

这其中有一种特殊情况,如果传输的指针是指向CPU上的静态变量的,且变量被__declspec(target(mic))声明,则alloc_if和free_if会被忽略。

对于in/out/inout语句来说,还有一个比较实用的语法,即传输数组的一部分。例如以下这段代码:

 1 typedef int ARRAY[10][10];
 2 int a[1000][500];
 3 int* p;
 4 ARRAY *p;
 5 int *r[10][10];
 6 int i,j;
 7 struct {int y;} x;
 8 #pragma offload... int(a)
 9 #pragma offload... out(a[i:j][:])
10 #pragma offload... in(p[0:100])
11 #pragma offload... in((*p)[5][:])
12 #pragma offload... out(x,y)

in/out语句可以只引用数组的一部分,数组的维度用“[]”表示。第8行是最常用的,传输的是,数组a的全部数据。第9行传输数组a的一部分,其中[i:j]规范第1维,i表示该维的起始位置,j表示个数第2维中中括号内部只有冒号,省略了前后,表示第2维是完整的。即传输的内容是a [i][0]~a[i+j-1][499]。如本句所示,长度参数(i,j)可以是变量。第10行的意思是传输p指向的数组中,从0起始的100个元素,本句说明即使传输的是指向动态数组的指针,也可以用数组的“[]”形式。第11行中,第1维只有一个参数5,意为第1维只有一个元素,即本句中传输的int[5][0]~int[5][9](ARRAY是int[10][10]的同义词,q是指向int[10][10]的指针)。第12行表示可以传输结构体的一部分。

  以上方式可以让我们很方便的传输数组的一部分,在节省传输时间的同时也减少了对代码的改动。在使用时需要注意,虽然传输的是数组的一部分,但在MIC卡端开辟内存空间时,任然开辟了从第1个元素开始的全部空间,所以一方面这种写法并没有减少内存占用,另一方面使用时任然要将数组视为整体使用。即当无视offload语句的时候。或者说假设程序在CPU端运行时,代码如何书写,在传输部分数组时,代码应使用同样的写法,这是为了避免维护两套代码而设计的。例如:有一个数组p[100],当in(p[2:10])时,在MIC端使用时,会在MIC端开辟12个元素的空间(p[0]-p[11]) ,并从主机内存中拷贝p[2]-p[11]的数据到MIC端内存,所以第一个有效元素任然写作p[2],而不是p[0];

同时也有两个关键字是针对这种用法的,即alloc和into。

正如前文所述,传输数组一部分的语法,会开辟全部(至少是从第一个元素开始的)的内存空间,但有时并不需要开辟这么多的空间,于是可以用alloc语法,限定开辟空间的范围,,如:

#pragma offload... in(p[10:100]:alloc(p[5:1000]))

这条offload语句首先在设备端开辟了1个1000个元素的数组p,数组下标的可用范围从5开始,即5~10004.然后将主机端从p[10]开始的100个元素,即p[10]-p[109]传到设备端的p[10]-p[109]的位置。需要注意的是,检查数句越界的责任人在程序员。

into语句可以将主机数组的一部分传递给另一个设备数组,反之亦然。例如:

#pragma offload... in(p[0:500]:into(p1[500:500]))

这条offload语句会将主机端p[0]开始的500个元素的值,复制到设备端p1[500]-p1[999]的相应位置。

使用这种方式需要由程序员把控正确性,尤其是有覆盖的情况,如:

#pragma offload... in(p[0:600] into(p1[0:600]))                                 in(p[60:400] : into(p1[100:400]))

这里的目的数组p1在两次传输中互相有重叠的地方,一个是0~599,另一个是100~499,两次传输在100~499的位置有重叠,这样会导致未定义的结果,即在同一个offload语句中,多个传输的顺序不一定。

要注意的是这里的into并不能简单的视作简单内存拷贝,因此不能在不同的维度的数组数组间传递数据,例如;

#ERROR!
int rank1[1000],rank2[10][100];
#pragma offload... out(rank1:into(rank2))

由于rank1和rank2维度不一致,因此不能直接传递。

时间: 2024-08-27 23:02:18

MIC中的数据传输的相关文章

Sftp和ftp 区别、工作原理等(服务器被动就是被动模式,PORT模式建立数据传输通道是由服务器端发起的,在PASV模式中,数据传输的通道的建立是由FTP客户端发起的)good

Sftp和ftp over ssh2的区别 最近使用SecureFx,涉及了两个不同的安全文件传输协议: -sftp -ftp over SSH2 这两种协议是不同的.sftp是ssh内含的协议,只要sshd服务器启动了,它就可用,它本身不需要ftp服务器启动.ftp over SSH2则象一个二传手. 1.SFTP的工作模式: 图1显示了SFTP的工作模式,它是作为SSH2的一个子服务工作的. 图 1 SFTP工作模式 2.FTP over SSH2 此协议还是基于ftp协议的.在此协议中SS

GPRS GPRS(General Packet Radio Service)是通用分组无线服务技术的简称,它是GSM移动电话用户可用的一种移动数据业务,属于第二代移动通信中的数据传输技术

GPRS 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . GPRS(General Packet Radio Service)是通用分组无线服务技术的简称,它是GSM移动电话用户可用的一种移动数据业务,属于第二代移动通信中的数据传输技术.GPRS可说是GSM的延续.GPRS和以往连续在频道传输的方式不同,是以封包(Packet)式来传输,因此使用者所负担的费用是以其传输资料单位计算,并非使用其整个频道,理论上较为便宜.GPRS的传输速率可提升至56甚至114Kbps.[1]

MIC中函数和变量的声明

c++/c使用 __declspec(target(mic))函数或变量声明 或 __attribute__((target(mic)))函数或变量声明 举例如下: __attribute__((target(mic))) int a; __attribute__((target(mic))) void func(); 这里注意attribute前后均是两个下划线,示例代码如下: #include<stdlib.h> #include<stdio.h> #include<st

Struts2 中的数据传输

1.     如何将参数从界面传递到Action? 你可以把Struts2中的Action看做是Struts1的Action+ActionForm,即只需在Action中定义相关的属性(要有getters/setters方法),然后界面传参的名称跟这些属性保持一致即可.普通的数据类型,将可自动转换.(空字符串转换为int类型时将报错) 2.     如何将数据从Action传输到JSP? 可通过多种方式传输 通过Action的属性传输 直接给action的属性赋值,在转向之后的JSP中,直接用标

MIC C编程(offload模式)

MIC C编程(offload模式) 编程特点 简单---隐藏大量细节,语法与OpenMPI类似(不需要开辟空间) 灵活---OpenMP MPI(但是用的不多)pThread等多种方式 传统---与CPU编程一脉相承 MIC C扩展语言结构 编译指导方式(#pragma) offload --表示之后的代码段将使用offload模式运行 运行在其他设备上(MIC) --标识内存传递参数,传递过程对用户透明 不需要手动写代码控制何时传入.何时传出 不需要手动申请卡上内存空间 不需要讲卡上内存与主

ajax之前台和后台数据传输

Spring中ajax数据传输 由于项目需要用ajax提交数据,而不是form提交数据.因此我需要学习ajax,这也是我在开发小组做的最后一个东西,尽管由于暑假要去东软实训,这个ajax提交也没有做完,但对于数据的在前台和后台的传递是解决了. 如何把数据通过ajax从前台传到后台,在网上查询的方法都是通过"data:"把数据传到后台,但是后台"String endTime=request.getParameter("eTime");"时间的值是空

(转) 浅析HTML5在移动应用开发中的使用

(转)浅析HTML5在移动应用开发中的使用 (原)http://www.iteye.com/magazines/67 2012-03-07  来自 UECD.163.com  编辑 wangguo 有38498人浏览 收藏 html5 移动开发 app UI < > 猎头职位: 上海: Junior Product Manager 前言 HTML5的出现让移动平台的竞争由系统平台转向了浏览器之间:移动端的IE.Chrome.FireFox.Safari,亦或是新出现的浏览器,谁能达到在移动端对

IPC(中)

IPC(中) 1 Android中IPC方式 在第一篇IPC(上)中我们已经介绍了IPC的基础知识:序列化和Binder,本篇将详细介绍各种跨进程通讯方式.具体有如下几种: Intent中extras传递 共享文件 Binder ContentProvider Socket 1.1 Bundle 四大组件中的三大组件(Activity,Service,Receiver)都是支持在Intent中传递Bundle数据的,由于Bundle实现了Parcelable接口,所以他可以方便在不同进程间传输,

AJAX中success函数的执行顺序

1,问题,在上图中,数据传输正常,但是一直输出为空的p,再输出66, 2,原因,默认开启了异步加载, 3,解决方法,开启同步,或者在success中添加函数.