使用GCC(G ++)编译c ++ OpenACC并行CPU代码

刘易斯0112

尝试使用配置有--enable-languages=c,c++,lto --disable-multilib以下代码的GCC-9.3.0(g ++)编译OpenACC代码时,不使用多个内核,而如果使用pgc ++编译器编译相同的代码,则它确实使用多个内核。

g ++编译: g++ -lgomp -Ofast -o jsolve -fopenacc jsolvec.cpp

pgc ++编译: pgc++ -o jsolvec.exe jsolvec.cpp -fast -Minfo=opt -ta=multicore

来自OpenACC Tutorial1 / solver https://github.com/OpenACCuserGroup/openacc-users-group.git的代码

// Jacobi iterative method for solving a system of linear equations
// This is guaranteed to converge if the matrix is diagonally dominant,
// so we artificially force the matrix to be diagonally dominant.
//  See https://en.wikipedia.org/wiki/Jacobi_method
//
//  We solve for vector x in Ax = b
//    Rewrite the matrix A as a
//       lower triangular (L),
//       upper triangular (U),
//    and diagonal matrix (D).
//
//  Ax = (L + D + U)x = b
//
//  rearrange to get: Dx = b - (L+U)x  -->   x = (b-(L+U)x)/D
//
//  we can do this iteratively: x_new = (b-(L+U)x_old)/D

// build with TYPE=double (default) or TYPE=float
// build with TOLERANCE=0.001 (default) or TOLERANCE= any other value
// three arguments:
//   vector size
//   maximum iteration count
//   frequency of printing the residual (every n-th iteration)

#include <cmath>
#include <omp.h>
#include <cstdlib>
#include <iostream>
#include <iomanip>

using std::cout;

#ifndef TYPE
#define TYPE double
#endif

#define TOLERANCE 0.001

void
init_simple_diag_dom(int nsize, TYPE* A)
{
  int i, j;

  // In a diagonally-dominant matrix, the diagonal element
  // is greater than the sum of the other elements in the row.
  // Scale the matrix so the sum of the row elements is close to one.
  for (i = 0; i < nsize; ++i) {
    TYPE sum;
    sum = (TYPE)0;
    for (j = 0; j < nsize; ++j) {
      TYPE x;
      x = (rand() % 23) / (TYPE)1000;
      A[i*nsize + j] = x;
      sum += x;
    }
    // Fill diagonal element with the sum
    A[i*nsize + i] += sum;

    // scale the row so the final matrix is almost an identity matrix
    for (j = 0; j < nsize; j++)
      A[i*nsize + j] /= sum;
  }
} // init_simple_diag_dom

int
main(int argc, char **argv)
{
  int nsize; // A[nsize][nsize]
  int i, j, iters, max_iters, riter;
  double start_time, elapsed_time;
  TYPE residual, err, chksum;
  TYPE *A, *b, *x1, *x2, *xnew, *xold, *xtmp;

  // set matrix dimensions and allocate memory for matrices
  nsize = 0;
  if (argc > 1)
    nsize = atoi(argv[1]);
  if (nsize <= 0)
    nsize = 1000;

  max_iters = 0;
  if (argc > 2)
    max_iters = atoi(argv[2]);
  if (max_iters <= 0)
    max_iters = 5000;

  riter = 0;
  if (argc > 3)
    riter = atoi(argv[3]);
  if (riter <= 0)
    riter = 200;

  cout << "nsize = " << nsize << ", max_iters = " << max_iters << "\n";

  A = new TYPE[nsize*nsize];

  b = new TYPE[nsize];
  x1 = new TYPE[nsize];
  x2 = new TYPE[nsize];

  // generate a diagonally dominant matrix
  init_simple_diag_dom(nsize, A);

  // zero the x vectors, random values to the b vector
  for (i = 0; i < nsize; i++) {
    x1[i] = (TYPE)0.0;
    x2[i] = (TYPE)0.0;
    b[i] = (TYPE)(rand() % 51) / 100.0;
  }

  start_time = omp_get_wtime();

  //
  // jacobi iterative solver
  //

  residual = TOLERANCE + 1.0;
  iters = 0;
  xnew = x1;    // swap these pointers in each iteration
  xold = x2;
  while ((residual > TOLERANCE) && (iters < max_iters)) {
    ++iters;
    // swap input and output vectors
    xtmp = xnew;
    xnew = xold;
    xold = xtmp;

    #pragma acc parallel loop
    for (i = 0; i < nsize; ++i) {
      TYPE rsum = (TYPE)0;
      #pragma acc loop reduction(+:rsum)
      for (j = 0; j < nsize; ++j) {
        if (i != j) rsum += A[i*nsize + j] * xold[j];
      }
      xnew[i] = (b[i] - rsum) / A[i*nsize + i];
    }
    //
    // test convergence, sqrt(sum((xnew-xold)**2))
    //
    residual = 0.0;
    #pragma acc parallel loop reduction(+:residual)
    for (i = 0; i < nsize; i++) {
      TYPE dif;
      dif = xnew[i] - xold[i];
      residual += dif * dif;
    }
    residual = sqrt((double)residual);
    if (iters % riter == 0 ) cout << "Iteration " << iters << ", residual is " << residual << "\n";
  }
  elapsed_time = omp_get_wtime() - start_time;
  cout << "\nConverged after " << iters << " iterations and " << elapsed_time << " seconds, residual is " << residual << "\n";

  //
  // test answer by multiplying my computed value of x by
  // the input A matrix and comparing the result with the
  // input b vector.
  //
  err = (TYPE)0.0;
  chksum = (TYPE)0.0;

  for (i = 0; i < nsize; i++) {
    TYPE tmp;
    xold[i] = (TYPE)0.0;
    for (j = 0; j < nsize; j++)
      xold[i] += A[i*nsize + j] * xnew[j];
    tmp = xold[i] - b[i];
    chksum += xnew[i];
    err += tmp * tmp;
  }
  err = sqrt((double)err);
  cout << "Solution error is " << err << "\n";
  if (err > TOLERANCE)
    cout << "****** Final Solution Out of Tolerance ******\n" << err << " > " << TOLERANCE << "\n";

  delete A;
  delete b;
  delete x1;
  delete x2;
  return 0;
}
摇摆

GCC尚不支持使用OpenACC将并行循环调度到多核CPU上。当然,使用OpenMP可以解决此问题,并且您可以将代码与混合的OpenACC(用于代码卸载,如代码中已存在的)和OpenMP指令(用于CPU并行化,代码中尚不存在的)混合使用,以便采用相应的机制取决于是否使用-fopenaccvs.进行编译-fopenmp

就像PGI所做的一样,它当然可以在GCC中得到支持。我们当然可以实施,但尚未安排好,尚未为GCC筹集资金。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Eclipse使用G ++而不是GCC编译C代码

来自分类Dev

C代码:for循环使用gcc编译但无法运行

来自分类Dev

无法使用g ++用C ++代码编译C库

来自分类Dev

使用g ++编译C ++源代码时的VLA

来自分类Dev

使用g ++编译C ++源代码时的VLA

来自分类Dev

标量初始化程序代码中的多余元素使用gcc编译,但不使用g ++编译

来自分类Dev

C / C ++项目使用Xcode编译,但不能使用gcc / g ++编译

来自分类Dev

代码在c ++中无法在g ++中编译

来自分类Dev

使用多个编译器编译C代码

来自分类Dev

并行代码CPU使用率问题

来自分类Dev

如何使用gcc 4.4.7编译具有C ++ 11功能的C ++代码

来自分类Dev

使用CMake使用CUDA代码编译c ++

来自分类Dev

使用'asm'指令编译C源代码

来自分类Dev

使用__float128编译C ++代码

来自分类Dev

使用shellscript编译我的源代码(C)

来自分类Dev

使用Magick ++和openMPI编译C ++代码

来自分类Dev

无法编译使用librsvg的微型C代码

来自分类Dev

Cygwin上的GCC在C代码中使用全局NASM符号时会编译废话

来自分类Dev

在OpenCV中编译c ++代码时遇到问题-DisplayImage.cpp(使用gcc和CMake)

来自分类Dev

使用ubuntu Ubuntu 12.04.5 LTS编译python和C ++代码的问题:gcc问题

来自分类Dev

使用GCC编译教科书中提供的C代码时出现错误

来自分类Dev

使用g ++的C ++ XInput编译

来自分类Dev

使用gcc和g ++分别编译带有C和C ++文件的项目?

来自分类Dev

代码使用clang编译,但不使用gcc编译

来自分类Dev

如何使用本机编译器(g ++)编译并运行llc-3.4生成的C ++代码?

来自分类Dev

什么会导致 gcc 部分编译 C 代码?

来自分类Dev

在minGW-W64 g ++中编译的C ++代码无法在Ubuntu g ++中编译

来自分类Dev

ming32-make使用g ++而不是cc或gcc来编译.c源文件

来自分类Dev

修复ms编译器C代码以在gcc中进行编译

Related 相关文章

  1. 1

    Eclipse使用G ++而不是GCC编译C代码

  2. 2

    C代码:for循环使用gcc编译但无法运行

  3. 3

    无法使用g ++用C ++代码编译C库

  4. 4

    使用g ++编译C ++源代码时的VLA

  5. 5

    使用g ++编译C ++源代码时的VLA

  6. 6

    标量初始化程序代码中的多余元素使用gcc编译,但不使用g ++编译

  7. 7

    C / C ++项目使用Xcode编译,但不能使用gcc / g ++编译

  8. 8

    代码在c ++中无法在g ++中编译

  9. 9

    使用多个编译器编译C代码

  10. 10

    并行代码CPU使用率问题

  11. 11

    如何使用gcc 4.4.7编译具有C ++ 11功能的C ++代码

  12. 12

    使用CMake使用CUDA代码编译c ++

  13. 13

    使用'asm'指令编译C源代码

  14. 14

    使用__float128编译C ++代码

  15. 15

    使用shellscript编译我的源代码(C)

  16. 16

    使用Magick ++和openMPI编译C ++代码

  17. 17

    无法编译使用librsvg的微型C代码

  18. 18

    Cygwin上的GCC在C代码中使用全局NASM符号时会编译废话

  19. 19

    在OpenCV中编译c ++代码时遇到问题-DisplayImage.cpp(使用gcc和CMake)

  20. 20

    使用ubuntu Ubuntu 12.04.5 LTS编译python和C ++代码的问题:gcc问题

  21. 21

    使用GCC编译教科书中提供的C代码时出现错误

  22. 22

    使用g ++的C ++ XInput编译

  23. 23

    使用gcc和g ++分别编译带有C和C ++文件的项目?

  24. 24

    代码使用clang编译,但不使用gcc编译

  25. 25

    如何使用本机编译器(g ++)编译并运行llc-3.4生成的C ++代码?

  26. 26

    什么会导致 gcc 部分编译 C 代码?

  27. 27

    在minGW-W64 g ++中编译的C ++代码无法在Ubuntu g ++中编译

  28. 28

    ming32-make使用g ++而不是cc或gcc来编译.c源文件

  29. 29

    修复ms编译器C代码以在gcc中进行编译

热门标签

归档