我希望通过使用OpenACC来减少代码的运行时间,但不幸的是,当我使用OpenACC时,输出变为零。
sajad。**
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <openacc.h>
#include<time.h>
#include <string.h>
#include <malloc.h>
#define NX 201
#define NY 101
#define NZ 201
int main(void)
{
int i, j, k, l, m;
static double tr, w;
static double dt = 9.5e-9, t;
static double cu[NZ];
static double AA[NX][NY][NZ] , CC[NX][NY][NZ] , BB[NX][NY][NZ] ;
static double A[NX][NY][NZ] , B[NX][NY][NZ] , C[NX][NY][NZ] ;
FILE *file;
file = fopen("BB-and-A.csv", "w");
t = 0.;
#pragma acc data copyin( tr, w,dt, t),copy(B ,A , C,AA , CC,BB,cu )
{
for (l = 1; l < 65; l++) {
#pragma acc kernels loop private(i, j,k)
for (i = 1; i < NX - 1; i++) {
for (j = 0; j < NY - 1; j++) {
for (k = 1; k < NZ - 1; k++) {
A[i][j][k] = A[i][j][k]
+ 1. * (B[i][j][k] - AA[i][j][k - 1]);
}
}
}
#pragma acc kernels loop private(i, j,k)
for (i = 1; i < NX - 1; i++) { /* BB */
for (j = 1; j < NY - 1; j++) {
for (k = 0; k < NZ - 1; k++) {
B[i][j][k] = B[i][j][k]
+ 1.* (BB[i][j][k] - A[i - 1][j][k]);
}
}
}
#pragma acc kernels
for (m = 1; m < NZ - 1; m++) {
tr = t - (double)(m)*5 / 1.5e8;
if (tr <= 0.)
cu[m] = 0.;
else {
w = (tr / 0.25e-6)*(tr / 0.25e-6);
cu[m] =1666*w / (w + 1.)*exp(-tr / 2.5e-6) ;
cu[m] = 2*cu[m];
}
A[10][60][m] = -cu[m];
}
#pragma acc update self(B)
fprintf(file, "%e, %e \n", t*1e6, -B[22][60][10] );
t = t + dt;
}
}
fclose(file);
}
答案 0 :(得分:0)
这里的问题是“copyin(tr,w,dt,t)”,特别是“t”变量。通过将这些标量放在数据子句中,您需要将主机之间的同步作为设备副本进行管理。因此,当您更新主机上的变量(即“t = t + dt;”)时,您需要使用新值更新设备副本。
此外,“tr”上存在潜在的竞争条件,因为设备代码现在将是共享设备变量而不是私有副本。
尽管如此,最简单的方法是不要将这些标量放在数据子句中。默认情况下,OpenACC会对标量进行私有化,因此无需自行管理它们。在这种情况下,它的值将作为参数传递给CUDA内核。
修复代码更改:
#pragma acc data copyin( tr, w,dt, t),copy(B ,A , C,AA , CC,BB,cu )
为:
#pragma acc data copy(B ,A , C,AA , CC,BB,cu )
请注意,不需要将循环索引放在private子句中,因为它们是隐式私有的。