OpenACC——#pragma acc kernels

#pragma acc kernels:

1、kernels构件将需要进行并行化的区域,编译成一系列可以在设备上运行的CUDA kernel,这也是为什么起名叫“kernels”的原因吧。

2、kernels区域结束时,会有一个隐式的同步障碍,线程到此等待,直到所有的线程到达此处。

3、将kernels区域映射成CUDA内核时,线程的网格维度和块维度等参数由编译器自行进行选择,编译器可以根据设备环境自动选择合适的参数。

4、kernels并不是完全按照制导语句进行并行化,如果发现问题,比如存在数据依赖,会拒绝并行化。

1、单重循环:

代码示例:

#include <iostream>
using namespace std;
#define N 256
int main()
{
	int i, a[N], b[N], c[N];
	for(i = 0; i < N; i++)
	{
		a[i] = 0;
		b[i] = c[i] = i;
	}
	#pragma acc kernels
	for(i=0; i < N; i++)
	{
		a[i] = b[i] + c[i];
	}
	cout << "a[N-1]=" << a[N-1] << endl;
   return 0;
}

编译结果:

在编译命令是加入-Minfo可以显示编译信息

从编译信息可以看出,kernels之后的for循环确实被并行化了,#pragma acc loop gang,vector(128)是编译器选择的并行模式及参数。

2、区域内双循环:

代码示例:

#include <iostream>
using namespace std;
#define N 1024
int main()
{
	int i, a[N], b[N], c[N];
	for(i = 0; i < N; i++)
	{
		a[i] = 0;
		b[i] = c[i] = i;
	}
	#pragma acc kernels
    {
        for(i=0; i < N; i++)
        {
            a[i] = b[i] + c[i];
        }
        for(i=0; i <= N/2; i++)
        {
            b[i] = 2 * a[i];
        }
    }
	cout << "b[N/2]=" << b[N/2] << endl;
   return 0;
}

反馈信息:

在环境变量中加入下面代码,可以查看相关的CUDA内核配置

export PGI_ACC_NOTIFY=1

上面的代码的反馈信息如下:

 从上面的信息可以看出,两个循环都被并行化,且不同循环可以根据需要灵活的自行设置参数。

注意:对于区域内的双循环,要将两个循环用大括号括起来,划定这个并行区域,否则只会将第一个循环并行化。

3、双重循环

示例代码:

#include <iostream>
using namespace std;
#define N 256
#define M 128
int main()
{
	int i, j, a[M][N], b[M][N], c[M][N];
	for(i = 0; i < M; i++)
	{
        for(j = 0; j < N; j++)
        {
            a[i][j] = -1;
            b[i][j] = c[i][j] = i+j;
        }
	}
	#pragma acc kernels
    for(i=0; i < M; i++)
    {
        for(j = 0; j < N; j++)
        {
            a[i][j] = b[i][j] + c[i][j];
        }
    }
        
	cout << "a[M-1][N-1]=" << a[M-1][N-1] << endl;
   return 0;
}

编译信息:

从中可以看出两个循环都被并行化。执行的配置信息自行查看吧,这里就不展示了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值