#pragma acc parallel:

1、遇到一个parallel构件时,程序就创建一个或多个gang来执行这个并行区域。

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

3、parallel导语自动探测结构块代码内的并行性,存在数据依赖时拒绝并行化。

4、在没有loop导语的情况下,parallel只有一个gang来进行并行化。在使用loop导语的情况下,默认数据是没有依赖的,如果确实存在数据依赖,那后果自负。

5、在一个parallel区域内不管有多少个循环,都只会编译成一个CUDA内核,也就是不管每个循环的迭代次数是否相等,都是采用相同的并行参数。

1、单重循环:

1.1 只有一个gang

示例代码:

#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] = -1;
        b[i] = c[i] = i;
	}
	#pragma acc parallel
    for(i=0; i < N; i++)
    {
        a[i] = b[i] + c[i];
    }    
	cout << "a[N-1]=" << a[N-1] << endl;
   return 0;
}

反馈信息:

可以看出,num_gangs=1,确实只有一个gang。

1.2 使用loop制导语句,可以使用多个gang进行并行。

示例代码:

#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] = -1;
        b[i] = c[i] = i;
	}
	#pragma acc parallel
    #pragma acc loop
    for(i=0; i < N; i++)
    {
        a[i] = b[i] + c[i];
    }    
	cout << "a[N-1]=" << a[N-1] << endl;
   return 0;
}

 反馈信息:

 从上面可以看出,num_gangs = 2,并行使用的gang多了。

1.3 区域内多个循环采用相同的并行参数

示例代码:

#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] = -1;
        b[i] = c[i] = i;
	}
	#pragma acc parallel
    {
        for(i=0; i < N; i++)
        {
            a[i] = c[i] + 1;
        }  
        for(i=0; i < N; i++)
        {
            b[i] = c[i] + 2;
        }  
    }
      
	cout << "a[N-1]=" << a[N-1] << endl;
   return 0;
}

反馈信息:

从反馈信息可以看出,两个循环使用了相同的参数。 

2、双重循环:

2.1 只用parallel:

示例代码:

#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 parallel
    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;
}

编译信息:

可以看出,内层循环被并行化执行。

2.2 加loop导语:

示例代码:

#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 parallel
    #pragma acc loop
    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;
}

编译信息:

可以看出,双层循环都被并行执行,是按照一维组织的。

 

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐