繁体   English   中英

PGI 编译器的 OpenACC 性能不佳

[英]OpenACC bad performance with PGI Compiler

我正在尝试使用OpenACC制作我的期末论文,以提高代码的性能。 但是,优化的代码比我尝试了很多东西的串行代码差,但没有一个有效。 如果有人可以帮助我,我将不胜感激。

1332    void SOR()
1333    {
1334        iteracoes_solver = 0;
1335        
1336        
1337        {
1338    
1339            #pragma acc data copy(AC_lin[2:nx*ny], Po1_lin[2:nx*ny], AUXW1[2:nx*ny], Qo_lin[2:nx*ny], Tgx[2:nx*ny], Po3_lin[2:nx*ny], Tgy[2:nx*ny], P_auxi[2:nx*ny], vetErro[2:nx*ny]) \
1340            copyin(AC_lin[2:nx*ny], Tgx[2:nx*ny], Tgy[2:nx*ny])
1341            while (iteracoes_solver < 10001)
1342            {
1343    
1344                
1345                //#pragma acc kernels loop private(n) copyin(P_auxi[0:nxy]) vector(512)
1346                for (n = 1; n <= nxy; n++)    
1347                    P_auxi[n] = Po3_lin[n];
1348    
1349                
1350                {
1351    
1352                    erro = 0.0;
1353    
1354                    if (total_iter == 10000)
1355                    {
1356                        printf("---> TEMPO=%g\n---> Numero maximo de iteracoes atingido no solver\n---> Corrigir parametros\n", tempo_atual);//getch();
1357                        exit_tool();
1358                    }
1359    
1360                    n = 1;
1361                    auxf1 = (AC_lin[n] * Po1_lin[n]) + (AUXW1[n] * Qo_lin[n]) + (Tgx[n] * Po3_lin[n + 1]) + (Tgy[n] * Po3_lin[n + nx]) + ((1 - AUXW1[n]));
1362                    Paux = auxf1 / (AC_lin[n] + Tgx[n] + Tgy[n] + (1 - AUXW1[n]));
1363                    Paux = (omega * Paux) + ((1.0 - omega) * P_auxi[n]);
1364                    vetErro[n] = fabs(Po3_lin[n] - Paux);
1365                    Po3_lin[n] = Paux;
1366    
1367                    n = nx;
1368                    auxf1 = (AC_lin[n] * Po1_lin[n]) + (AUXW1[n] * Qo_lin[n]) + (Tgx[n - 1] * Po3_lin[n - 1]) + (Tgy[n] * Po3_lin[n + nx]) + ((1 - AUXW1[n]));
1369                    Paux = auxf1 / (AC_lin[n] + Tgx[n - 1] + Tgy[n] + ((1 - AUXW1[n])));
1370                    Paux = (omega * Paux) + ((1.0 - omega) * P_auxi[n]);
1371                    vetErro[n] = fabs(Po3_lin[n] - Paux);
1372                    Po3_lin[n] = Paux;
1373    
1374                    auxi11 = nxy - nx;
1375    
1376                    n = auxi11 + 1;
1377                    auxf1 = (AC_lin[n] * Po1_lin[n]) + (AUXW1[n] * Qo_lin[n]) + (Tgx[n] * Po3_lin[n + 1]) + (Tgy[n - nx] * Po3_lin[n - nx]) + ((1 - AUXW1[n]));
1378                    Paux = auxf1 / (AC_lin[n] + Tgx[n] + Tgy[n - nx] + ((1 - AUXW1[n])));
1379                    Paux = (omega * Paux) + ((1.0 - omega) * P_auxi[n]);
1380                    vetErro[n] = fabs(Po3_lin[n] - Paux);
1381                    Po3_lin[n] = Paux;
1382    
1383                    n = nxy;
1384                    auxf1 = (AC_lin[n] * Po1_lin[n]) + (AUXW1[n] * Qo_lin[n]) + (Tgx[n - 1] * Po3_lin[n - 1]) + (Tgy[n - nx] * Po3_lin[n - nx]) + ((1 - AUXW1[n]));
1385                    Paux = auxf1 / (AC_lin[n] + Tgx[n - 1] + Tgy[n - nx] + ((1 - AUXW1[n])));
1386                    Paux = (omega * Paux) + ((1.0 - omega) * P_auxi[n]);
1387                    vetErro[n] = fabs(Po3_lin[n] - Paux);
1388                    Po3_lin[n] = Paux;
1389    
1390    
1391                   
1392                    #pragma acc parallel loop private(n)
1393                    for (n = 2; n < nx; n++)
1394                    {
1395                        auxf1 = (AC_lin[n] * Po1_lin[n]) + (AUXW1[n] * Qo_lin[n]) + (Tgx[n] * Po3_lin[n + 1]) + (Tgx[n - 1] * Po3_lin[n - 1]) + (Tgy[n] * Po3_lin[n + nx]) + ((1 - AUXW1[n]));
1396                        Paux = auxf1 / (AC_lin[n] + Tgx[n] + Tgx[n - 1] + Tgy[n] + ((1 - AUXW1[n])));
1397                        Paux = (omega * Paux) + ((1.0 - omega) * P_auxi[n]);
1398                        vetErro[n] = fabs(Po3_lin[n] - Paux);
1399                        Po3_lin[n] = Paux;
1400                    }
1401    
1402    
1403                    
1404                    #pragma acc parallel loop private(n)
1405                    for (j = 2; j < ny; j++)
1406                    {
1407                        auxi11 = nx * (j - 1);
1408    
1409                        n = auxi11 + 1;
1410                        auxf1 = (AC_lin[n] * Po1_lin[n]) + (AUXW1[n] * Qo_lin[n]) + (Tgx[n] * Po3_lin[n + 1]) + (Tgy[n] * Po3_lin[n + nx]) + (Tgy[n - nx] * Po3_lin[n - nx]) + ((1 - AUXW1[n]));
1411                        Paux = auxf1 / (AC_lin[n] + Tgx[n] + Tgy[n] + Tgy[n - nx] + ((1 - AUXW1[n])));
1412                        Paux = (omega * Paux) + ((1.0 - omega) * P_auxi[n]);
1413                        vetErro[n] = fabs(Po3_lin[n] - Paux);
1414                        Po3_lin[n] = Paux;
1415                    }
1416    
1417    
1418                    
1419                    //#pragma acc kernels
1420                    for (j = 2; j < ny; j++)
1421                    {
1422                        auxi11 = nx * (j - 1);
1423    
1424                        n = auxi11 + nx;
1425                        auxf1 = (AC_lin[n] * Po1_lin[n]) + (AUXW1[n] * Qo_lin[n]) + (Tgx[n - 1] * Po3_lin[n - 1]) + (Tgy[n] * Po3_lin[n + nx]) + (Tgy[n - nx] * Po3_lin[n - nx]) + ((1 - AUXW1[n]));
1426                        Paux = auxf1 / (AC_lin[n] + Tgx[n - 1] + Tgy[n] + Tgy[n - nx] + ((1 - AUXW1[n])));
1427                        Paux = (omega * Paux) + ((1.0 - omega) * P_auxi[n]);
1428                        vetErro[n] = fabs(Po3_lin[n] - Paux);
1429                        Po3_lin[n] = Paux;
1430    
1431                    }
1432    
1433                   
1434                    auxi11 = nxy - nx;
1435    
1436    
1437                   
1438                    //#pragma acc kernels
1439                    for (i = 2; i < nx; i++)
1440                    {
1441                        n = auxi11 + i;
1442                        auxf1 = (AC_lin[n] * Po1_lin[n]) + (AUXW1[n] * Qo_lin[n]) + (Tgx[n] * Po3_lin[n + 1]) + (Tgx[n - 1] * Po3_lin[n - 1]) + (Tgy[n - nx] * Po3_lin[n - nx]) + ((1 - AUXW1[n]));
1443                        Paux = auxf1 / (AC_lin[n] + Tgx[n] + Tgx[n - 1] + Tgy[n - nx] + ((1 - AUXW1[n])));
1444                        Paux = (omega * Paux) + ((1.0 - omega) * P_auxi[n]);
1445                        vetErro[n] = fabs(Po3_lin[n] - Paux);
1446                        Po3_lin[n] = Paux;
1447                    }
1448                }
1449                
1450    
1451                
1452                
1453                //#pragma acc kernels loop private(auxf1,Paux,i,j,n) vector(512) independent
1454                for (j = 2; j < ny; j++)
1455                {
1456                    for (i = 2 + (j % 2); i < nx; i += 2)
1457                    {
1458                        n = (nx * (j - 1)) + i;
1459                        auxf1 = (AC_lin[n] * Po1_lin[n]) + (AUXW1[n] * Qo_lin[n]) + (Tgx[n] * Po3_lin[n + 1]) + (Tgx[n - 1] * Po3_lin[n - 1]) + (Tgy[n] * Po3_lin[n + nx]) + (Tgy[n - nx] * Po3_lin[n - nx]) + ((1 - AUXW1[n]));
1460                        Paux = auxf1 / (AC_lin[n] + Tgx[n] + Tgx[n - 1] + Tgy[n] + Tgy[n - nx] + ((1 - AUXW1[n])));
1461                        Paux = (omega * Paux) + ((1.0 - omega) * P_auxi[n]);
1462                        vetErro[n] = fabs(Po3_lin[n] - Paux);
1463                        Po3_lin[n] = Paux;
1464                    }
1465                }
1466                
1467                
1468                //#pragma acc kernels loop private(auxf1,Paux,i,j,n) vector(512) independent
1469                for (j = 2; j < ny; j++)
1470                {
1471                    for (i = 3 - (j % 2); i < nx; i += 2)
1472                    {
1473                        n = (nx * (j - 1)) + i;
1474                        auxf1 = (AC_lin[n] * Po1_lin[n]) + (AUXW1[n] * Qo_lin[n]) + (Tgx[n] * Po3_lin[n + 1]) + (Tgx[n - 1] * Po3_lin[n - 1]) + (Tgy[n] * Po3_lin[n + nx]) + (Tgy[n - nx] * Po3_lin[n - nx]) + ((1 - AUXW1[n]));
1475                        Paux = auxf1 / (AC_lin[n] + Tgx[n] + Tgx[n - 1] + Tgy[n] + Tgy[n - nx] + ((1 - AUXW1[n])));
1476                        Paux = (omega * Paux) + ((1.0 - omega) * P_auxi[n]);
1477                        vetErro[n] = fabs(Po3_lin[n] - Paux);
1478                        Po3_lin[n] = Paux;
1479                    }
1480                }
1481                
1482                
1483                #pragma acc parallel loop private(n)
1484                for (n = 0; n < nxy; n++) {
1485                    erro += vetErro[n];
1486                }
1487    
1488                
1489                if ((erro / nxy < tol)) {
1490                    //#pragma omp cancel parallel
1491                    break;
1492                }
1493                iteracoes_solver += 1;
1494            }
1495    
1496        }
1497    }

我不能放所有的de代码,所以我放了一部分代码。 我评论了一些编译指示以供测试。 当我的 nx=ny >=1000 时,串行代码优于优化代码。 我不明白的另一件事是我删除了代码的所有 pragma,并运行 PGI 编译器来优化代码,串行代码更好,我不知道为什么。 最后,我有两个问题:

1 - 我做错了什么? 2 - 为什么没有编译指示的代码比串行代码差?

最好的问候,布雷诺。

更新:我忘了把编译信息。 我运行代码

pgcc -ta=multicore -Minfo=all file.c -o file.exe

并生成

 1360, FMA (fused multiply-add) instruction(s) generated
   1392, Generating Multicore code
       1393, #pragma acc loop gang
   1393, FMA (fused multiply-add) instruction(s) generated
   1404, Generating Multicore code
       1405, #pragma acc loop gang
   1405, FMA (fused multiply-add) instruction(s) generated
   1420, FMA (fused multiply-add) instruction(s) generated
   1439, FMA (fused multiply-add) instruction(s) generated
   1456, FMA (fused multiply-add) instruction(s) generated
   1471, FMA (fused multiply-add) instruction(s) generated
   1483, Generating Multicore code
       1484, #pragma acc loop gang
   1485, Generating implicit reduction(+:erro)

通常,使用 OMP 功能会导致大量上下文切换,这实际上会减慢代码的执行速度。 SO OMP 非常适合 I/O 绑定代码,但不适用于 CPU 绑定代码。

重复计算应移到循环之前:

什么是: 2:nx*ny

索引变量的“范围”应尽可能合理。 因此,在编写for()语句时,第一个参数还应该声明索引变量,对于大多数这些for()语句来说,它类似于:

for( size_t i = 0; .,.. )

关于: 1.0这是一个double文字,但代码正在调用fabs() ,它需要一个float ,建议文字是: 1.0f

与几个计算一样,这个计算: (1.0 - omega)不会改变,所以这个计算应该在循环之前只进行一次

当我们没有看到串行代码时,我们怎么能说为什么没有编译指示的代码比串行代码慢?

关于:

while (iteracoes_solver < 10001)

变量: iteracoes_solver被初始化为 0,并且在发布的代码中的任何地方都不会增加。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM