1、async子语:
async子语可以出现在parallel构件或者kernels构件上,也可以出现在enter data、exit data、update、wait导语上。没有async子语的时候,在执行任何后续代码之前,主机线程会一直等待直至计算构件结束或者数据操作完成;如果有async子语,在主机线程继续执行构件或导语后面代码的同时,parallel、kernels构件区域或数据操作可以被异步地处理。
2、wait子语:
wait子语可以出现在parallel构件或者kernels构件上,也可以出现在enter data、exit data、update导语上。没有wait子语时,在设备上,关联的计算操作或更新操作会被立即压入队列、启动或执行;如果有wait子语,计算、数据更新操作可能不会被立即启动或执行,直到本线程在这个位置前压入关联异步设备活动队列的所有操作都已经完成。
3、wait导语:
wait导语将引发主机线程等待,直到在此之前压入队列的所有相关异步活动都已经完成。保证其他线程压入队列的操作已经完成,要求在那些线程间进行额外的同步操作。
示例代码:
#include<iostream>
#include<stdlib.h>
int main()
{
int N = 10240000, M = 200;
int *a, *b, *c;
a = (int*)malloc(sizeof(int)*N);
b = (int*)malloc(sizeof(int)*N);
c = (int*)malloc(sizeof(int)*N);
#pragma acc enter data create(a[0:N]) async
for (int j=1; j<=M; j++)
#pragma acc parallel loop async
for(int i=0; i<M; i++)
a[i] = (i + j)/2;
for(int j=1; j<=M; j++)
for(int i=0; i<N; i++)
b[i] =(i+j)/3;
#pragma acc update host(a[0:N]) async
#pragma acc wait
for(int i=0; i<N; i++)
c[i] = a[i] + b[i];
#pragma acc update device(a[0:N])
#pragma acc exit data delete(a[0:N])
std::cout<<"c[1] = "<<c[1]<<std::endl;
free(a);
free(b);
free(c);
return 0;
}
主机将第10~14行对应的内核提交给默认的队列后,立即返回,接着继续执行第16~18行的代码。第19行update导语上添加async子语,是为了防止进行立即传输,避免未完成赋值的变量复制到主机上。第20行的wait导语让程序在此等待,直到多有异步队列中的所有操作都完成。