▶ 书上第二章,用一系列步骤优化梯度下降法解线性方程组。才发现 PGI community 编译器不支持 Windows 下的 C++ 编译(有 pgCC 命令但是不支持 .cpp 文件,要专业版才支持),以后 OpenACC - C++ 全盘转向 Ubuntu 中。

● 代码

 // matrix.h
#pragma once
#include <cstdlib> struct matrix
{
unsigned int num_rows;
unsigned int nnz;
unsigned int *row_offsets;
unsigned int *cols;
double *coefs;
}; void allocate_3d_poission_matrix(matrix &A, int N)
{
const int num_rows = (N + ) * (N + ) * (N + );
A.num_rows = num_rows;
A.row_offsets = (unsigned int*)malloc((num_rows + ) * sizeof(unsigned int));
A.cols = (unsigned int*)malloc( * num_rows * sizeof(unsigned int));
A.coefs = (double*)malloc( * num_rows * sizeof(double)); const int ystride = N, zstride = N * N;
int i, j, n, nnz, offsets[];
double coefs[]; i = ;
for (int z = -; z <= ; z++)
{
for (int y = -; y <= ; y++)
{
for (int x = -; x <= ; x++)
{
offsets[i] = zstride * z + ystride * y + x;
if (x == && y == && z == )
coefs[i] = ;
else
coefs[i] = -;
i++;
}
}
}
nnz = ;
for (i = ; i < num_rows; i++)
{
A.row_offsets[i] = nnz;
for (j = ; j < ; j++)
{
n = i + offsets[j];
if (n >= && n<num_rows)
{
A.cols[nnz] = n;
A.coefs[nnz] = coefs[j];
nnz++;
}
}
}
A.row_offsets[num_rows] = nnz;
A.nnz = nnz;
} void free_matrix(matrix &A)
{
unsigned int *row_offsets = A.row_offsets, *cols = A.cols;
double *coefs = A.coefs;
free(row_offsets);
free(cols);
free(coefs);
}
 // matrix_function.h
#pragma once
#include "vector.h"
#include "matrix.h" void matvec(const matrix& A, const vector& x, const vector &y)
{ const unsigned int num_rows = A.num_rows;
unsigned int *row_offsets = A.row_offsets, *cols = A.cols;
double *Acoefs = A.coefs, *xcoefs = x.coefs, *ycoefs = y.coefs; for (int i = ; i < num_rows; i++)
{
const int row_start = row_offsets[i], row_end = row_offsets[i + ];
double sum = ;
for (int j = row_start; j < row_end; j++)
sum += Acoefs[j] * xcoefs[cols[j]];
ycoefs[i] = sum;
}
}
 // vector.h
#pragma once
#include<cstdlib>
#include<cmath> struct vector
{
unsigned int n;
double *coefs;
}; void allocate_vector(vector &v, const unsigned int n)
{
v.n = n;
v.coefs = (double*)malloc(n * sizeof(double));
} void free_vector(vector &v)
{
v.n = ;
free(v.coefs);
} void initialize_vector(vector &v, const double val)
{
for (int i = ; i < v.n; i++)
v.coefs[i] = val;
}
 // vector_function.h
#pragma once
#include<cstdlib>
#include "vector.h" double dot(const vector& x, const vector& y)
{
const unsigned int n = x.n;
double sum = , *xcoefs = x.coefs, *ycoefs = y.coefs; for (int i = ; i < n; i++)
sum += xcoefs[i] * ycoefs[i];
return sum;
} void waxpby(double alpha, const vector &x, double beta, const vector &y, const vector& w)
{
const unsigned int n = x.n;
double *xcoefs = x.coefs, *ycoefs = y.coefs, *wcoefs = w.coefs; for (int i = ; i < n; i++)
wcoefs[i] = alpha * xcoefs[i] + beta * ycoefs[i];
}
 // main.cpp
#include <cstdlib>
#include <cstdio>
#include <chrono> #include "vector.h"
#include "vector_functions.h"
#include "matrix.h"
#include "matrix_functions.h" using namespace std::chrono; #define N 200
#define MAX_ITERS 100
#define TOL 1e-12 int main()
{
int iter;
double normr, rtrans, oldtrans, alpha;
vector x, p, Ap, b, r;
matrix A;
high_resolution_clock::time_point t1, t2; allocate_3d_poission_matrix(A, N);
allocate_vector(x, A.num_rows);
allocate_vector(p, A.num_rows);
allocate_vector(Ap, A.num_rows);
allocate_vector(b, A.num_rows);
allocate_vector(r, A.num_rows);
printf("Rows: %d, nnz: %d\n", A.num_rows, A.row_offsets[A.num_rows]); initialize_vector(x, );
initialize_vector(b, ); // 计算一个初始 r
waxpby(1.0, x, 0.0, x, p);
matvec(A, p, Ap);
waxpby(1.0, b, -1.0, Ap, r);
rtrans = dot(r, r);
normr = sqrt(rtrans); t1 = high_resolution_clock::now();
for(iter = ; iter < MAX_ITERS && normr > TOL; iter++)
{
// 更新 p 和 rtrans
if (iter == )
waxpby(1.0, r, 0.0, r, p);
else
{
oldtrans = rtrans;
rtrans = dot(r, r);
waxpby(1.0, r, rtrans / oldtrans, p, p);
} // 计算步长 alpha,用的是上一次的 rtran
matvec(A, p, Ap);
alpha = rtrans / dot(Ap, p);
normr = sqrt(rtrans); // 更新 x 和 r
waxpby(1.0, x, alpha, p, x);
waxpby(1.0, r, -alpha, Ap, r); if (iter % == )
printf("Iteration: %d, Tolerance: %.4e\n", iter, normr);
}
t2 = high_resolution_clock::now();
duration<double> time = duration_cast<duration<double>>(t2 - t1);
printf("Iterarion: %d, error: %e, time: %f s\n", iter, normr, time.count()); free_matrix(A);
free_vector(x);
free_vector(p);
free_vector(Ap);
free_vector(b);
free_vector(r);
//getchar();
return ;
}

● 输出结果,WSL

// WSL:
cuan@CUAN:/mnt/d/Code/ParallelProgrammingWithOpenACC-master/Chapter02/cpp$ pgc++ -std=c++ -acc -fast main.cpp -o acc.exe
cuan@CUAN:/mnt/d/Code/ParallelProgrammingWithOpenACC-master/Chapter02/cpp$ ./acc.exe
Rows: , nnz:
Iteration: , Tolerance: 4.0067e+08
Iteration: , Tolerance: 1.8772e+07
Iteration: , Tolerance: 6.4359e+05
Iteration: , Tolerance: 2.3202e+04
Iteration: , Tolerance: 8.3565e+02
Iteration: , Tolerance: 3.0039e+01
Iteration: , Tolerance: 1.0764e+00
Iteration: , Tolerance: 3.8360e-02
Iteration: , Tolerance: 1.3515e-03
Iteration: , Tolerance: 4.6209e-05
Iterarion: , error: 1.993399e-06, time: 17.065934 s // Ubuntu:
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/cpp$ pgc++ -std=c++ -acc -fast -Minfo -ta=tesla main.cpp -o no_acc.exe
initialize_vector(vector &, double):
, include "vector.h"
, Memory set idiom, loop replaced by call to __c_mset8
dot(const vector &, const vector &):
, include "vector_functions.h"
, Generated an alternate version of the loop
Generated vector simd code for the loop containing reductions
Generated prefetch instructions for the loop
Generated vector simd code for the loop containing reductions
Generated prefetch instructions for the loop
FMA (fused multiply-add) instruction(s) generated
waxpby(double, const vector &, double, const vector &, const vector &):
, include "vector_functions.h"
, Generated alternate versions of the loop
Generated vector and scalar versions of the loop; pointer conflict tests determine which is executed
Generated prefetch instructions for the loop
Generated vector and scalar versions of the loop; pointer conflict tests determine which is executed
Generated prefetch instructions for the loop
Generated vector and scalar versions of the loop; pointer conflict tests determine which is executed
Generated prefetch instructions for the loop
Loop unrolled times
FMA (fused multiply-add) instruction(s) generated
allocate_3d_poission_matrix(matrix &, int):
, include "matrix.h"
, Loop not fused: different loop trip count
, Loop not vectorized/parallelized: loop count too small
, Loop unrolled times (completely unrolled)
, Loop not vectorized: data dependency
matvec(const matrix &, const vector &, const vector &):
, include "matrix_functions.h"
, Generated an alternate version of the loop
Generated vector simd code for the loop containing reductions
Generated a prefetch instruction for the loop
Generated vector simd code for the loop containing reductions
Generated a prefetch instruction for the loop
FMA (fused multiply-add) instruction(s) generated
main:
, allocate_3d_poission_matrix(matrix &, int) inlined, size= (inline) file main.cpp ()
, Loop not fused: different loop trip count
, Loop not vectorized/parallelized: loop count too small
, Loop unrolled times (completely unrolled)
, Loop not fused: function call before adjacent loop
, Loop not vectorized: data dependency
, allocate_vector(vector &, unsigned int) inlined, size= (inline) file main.cpp ()
, allocate_vector(vector &, unsigned int) inlined, size= (inline) file main.cpp ()
, allocate_vector(vector &, unsigned int) inlined, size= (inline) file main.cpp ()
, allocate_vector(vector &, unsigned int) inlined, size= (inline) file main.cpp ()
, allocate_vector(vector &, unsigned int) inlined, size= (inline) file main.cpp ()
, initialize_vector(vector &, double) inlined, size= (inline) file main.cpp ()
, Memory set idiom, loop replaced by call to __c_mset8
, initialize_vector(vector &, double) inlined, size= (inline) file main.cpp ()
, Memory set idiom, loop replaced by call to __c_mset8
, waxpby(double, const vector &, double, const vector &, const vector &) inlined, size= (inline) file main.cpp ()
, Memory copy idiom, loop replaced by call to __c_mcopy8
, matvec(const matrix &, const vector &, const vector &) inlined, size= (inline) file main.cpp ()
, Loop not fused: dependence chain to sibling loop
, Generated an alternate version of the loop
Generated vector simd code for the loop containing reductions
Generated a prefetch instruction for the loop
Generated vector simd code for the loop containing reductions
Generated a prefetch instruction for the loop
FMA (fused multiply-add) instruction(s) generated
, waxpby(double, const vector &, double, const vector &, const vector &) inlined, size= (inline) file main.cpp ()
, Loop not fused: dependence chain to sibling loop
Generated vector and scalar versions of the loop; pointer conflict tests determine which is executed
Generated prefetch instructions for the loop
Loop unrolled times
Generated prefetches in scalar loop
FMA (fused multiply-add) instruction(s) generated
, dot(const vector &, const vector &) inlined, size= (inline) file main.cpp ()
, Loop not fused: function call before adjacent loop
Generated vector simd code for the loop containing reductions
Generated prefetch instructions for the loop
FMA (fused multiply-add) instruction(s) generated
, Loop not vectorized/parallelized: potential early exits
, waxpby(double, const vector &, double, const vector &, const vector &) inlined, size= (inline) file main.cpp ()
, Memory copy idiom, loop replaced by call to __c_mcopy8
, dot(const vector &, const vector &) inlined, size= (inline) file main.cpp ()
, Loop not fused: dependence chain to sibling loop
Generated vector and scalar versions of the loop; pointer conflict tests determine which is executed
Generated vector simd code for the loop containing reductions
Generated prefetch instructions for the loop
FMA (fused multiply-add) instruction(s) generated
, waxpby(double, const vector &, double, const vector &, const vector &) inlined, size= (inline) file main.cpp ()
, Loop not fused: different controlling conditions
Generated vector and scalar versions of the loop; pointer conflict tests determine which is executed
Generated prefetch instructions for the loop
Loop unrolled times
Generated prefetches in scalar loop
FMA (fused multiply-add) instruction(s) generated
, matvec(const matrix &, const vector &, const vector &) inlined, size= (inline) file main.cpp ()
, Loop not fused: dependence chain to sibling loop
, Generated an alternate version of the loop
Generated vector simd code for the loop containing reductions
Generated a prefetch instruction for the loop
Generated vector simd code for the loop containing reductions
Generated a prefetch instruction for the loop
FMA (fused multiply-add) instruction(s) generated
, dot(const vector &, const vector &) inlined, size= (inline) file main.cpp ()
, Loop not fused: dependence chain to sibling loop
Generated vector and scalar versions of the loop; pointer conflict tests determine which is executed
Generated vector simd code for the loop containing reductions
Generated prefetch instructions for the loop
FMA (fused multiply-add) instruction(s) generated
, waxpby(double, const vector &, double, const vector &, const vector &) inlined, size= (inline) file main.cpp ()
, Loop not fused: dependence chain to sibling loop
Generated vector and scalar versions of the loop; pointer conflict tests determine which is executed
Loop not vectorized: data dependency
Generated vector and scalar versions of the loop; pointer conflict tests determine which is executed
Generated prefetch instructions for the loop
Loop unrolled times
Generated prefetches in scalar loop
FMA (fused multiply-add) instruction(s) generated
, waxpby(double, const vector &, double, const vector &, const vector &) inlined, size= (inline) file main.cpp ()
, Loop not fused: function call before adjacent loop
Generated vector and scalar versions of the loop; pointer conflict tests determine which is executed
Generated prefetch instructions for the loop
Loop unrolled times
Generated prefetches in scalar loop
FMA (fused multiply-add) instruction(s) generated
, free_matrix(matrix &) inlined, size= (inline) file main.cpp ()
, free_vector(vector &) inlined, size= (inline) file main.cpp ()
, free_vector(vector &) inlined, size= (inline) file main.cpp ()
, free_vector(vector &) inlined, size= (inline) file main.cpp ()
, free_vector(vector &) inlined, size= (inline) file main.cpp ()
, free_vector(vector &) inlined, size= (inline) file main.cpp ()
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/cpp$ ./no_acc.exe
Rows: , nnz:
Iteration: , Tolerance: 4.0067e+08
Iteration: , Tolerance: 1.8772e+07
Iteration: , Tolerance: 6.4359e+05
Iteration: , Tolerance: 2.3202e+04
Iteration: , Tolerance: 8.3565e+02
Iteration: , Tolerance: 3.0039e+01
Iteration: , Tolerance: 1.0764e+00
Iteration: , Tolerance: 3.8360e-02
Iteration: , Tolerance: 1.3515e-03
Iteration: , Tolerance: 4.6209e-05
Iterarion: , error: 1.993399e-06, time: 17182.560547 ms

● 优化后

 // matrix.h
#pragma once
#include <cstdlib> struct matrix
{
unsigned int num_rows;
unsigned int nnz;
unsigned int *row_offsets;
unsigned int *cols;
double *coefs;
}; void allocate_3d_poission_matrix(matrix &A, int N)
{
const int num_rows = (N + ) * (N + ) * (N + );
A.num_rows = num_rows;
A.row_offsets = (unsigned int*)malloc((num_rows + ) * sizeof(unsigned int));
A.cols = (unsigned int*)malloc( * num_rows * sizeof(unsigned int));
A.coefs = (double*)malloc( * num_rows * sizeof(double)); const int ystride = N, zstride = N * N;
int i, j, n, nnz, offsets[];
double coefs[]; i = ;
for (int z = -; z <= ; z++)
{
for (int y = -; y <= ; y++)
{
for (int x = -; x <= ; x++)
{
offsets[i] = zstride * z + ystride * y + x;
if (x == && y == && z == )
coefs[i] = ;
else
coefs[i] = -;
i++;
}
}
}
nnz = ;
for (i = ; i < num_rows; i++)
{
A.row_offsets[i] = nnz;
for (j = ; j < ; j++)
{
n = i + offsets[j];
if (n >= && n<num_rows)
{
A.cols[nnz] = n;
A.coefs[nnz] = coefs[j];
nnz++;
}
}
}
A.row_offsets[num_rows] = nnz;
A.nnz = nnz;
#pragma acc enter data copyin(A)
#pragma acc enter data copyin(A.row_offsets[0:num_rows+1],A.cols[0:nnz],A.coefs[0:nnz])
} void free_matrix(matrix &A)
{
unsigned int *row_offsets = A.row_offsets, *cols = A.cols;
double *coefs = A.coefs;
#pragma acc exit data delete(A.row_offsets,A.cols,A.coefs)
#pragma acc exit data delete(A)
free(row_offsets);
free(cols);
free(coefs);
}
 // matrix_function.h
#pragma once
#include "vector.h"
#include "matrix.h" void matvec(const matrix& A, const vector& x, const vector &y)
{
const unsigned int num_rows=A.num_rows;
unsigned int *restrict row_offsets=A.row_offsets, *restrict cols=A.cols;
double *restrict Acoefs=A.coefs, *restrict xcoefs=x.coefs, *restrict ycoefs=y.coefs; #pragma acc kernels copyin(cols[0:A.nnz],Acoefs[0:A.nnz],xcoefs[0:x.n])
#pragma acc loop device_type(nvidia) gang worker(8)
for(int i = ; i < num_rows; i++)
{
double sum = ;
const int row_start=row_offsets[i], row_end=row_offsets[i+];
#pragma acc loop device_type(nvidia) vector(32)
for(int j = row_start; j < row_end; j++)
sum += Acoefs[j] * xcoefs[cols[j]];
ycoefs[i] = sum;
}
}
 // vector.h
#pragma once
#include<cstdlib>
#include<cmath> struct vector
{
unsigned int n;
double *coefs;
}; void allocate_vector(vector &v, const unsigned int n)
{
v.n=n;
v.coefs=(double*)malloc(n*sizeof(double));
#pragma acc enter data create(v)
#pragma acc enter data create(v.coefs[0:n])
} void free_vector(vector &v)
{
#pragma acc exit data delete(v.coefs)
#pragma acc exit data delete(v)
v.n = ;
free(v.coefs);
} void initialize_vector(vector &v, const double val)
{
for (int i = ; i < v.n; i++)
v.coefs[i] = val;
#pragma acc update device(v.coefs[0:v.n])
}
 // vector_functions.h
#pragma once
#include<cstdlib>
#include "vector.h" double dot(const vector& x, const vector& y)
{
const unsigned int n = x.n;
double sum = , *xcoefs = x.coefs, *ycoefs = y.coefs; #pragma acc kernels
for (int i = ; i < n; i++)
sum += xcoefs[i] * ycoefs[i];
return sum;
} void waxpby(double alpha, const vector &x, double beta, const vector &y, const vector& w) const unsigned int n = x.n;
double *restrict xcoefs = x.coefs, *ycoefs = y.coefs, *wcoefs = w.coefs; #pragma acc kernels copy(wcoefs[:w.n],ycoefs[0:y.n]) copyin(xcoefs[0:x.n])
{
#pragma acc loop independent
for (int i = ; i<n; i++)
wcoefs[i] = alpha * xcoefs[i] + beta * ycoefs[i];
}
}

● 输出结果

// Ubuntu:
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/cpp$ pgc++ -fast -acc -Minfo main.cpp -ta=tesla
allocate_vector(vector &, unsigned int):
, include "vector.h"
, Accelerator clause: upper bound for dimension of array 'v' is unknown
Generating enter data create(v[:],v->coefs[:n])
free_vector(vector &):
, include "vector.h"
, Generating exit data delete(v[:],v->coefs[:])
initialize_vector(vector &, double):
, include "vector.h"
, Memory set idiom, loop replaced by call to __c_mset8
, Generating update device(v->coefs[:v->n])
dot(const vector &, const vector &):
, include "vector_functions.h"
, Generating implicit copyin(ycoefs[:n],xcoefs[:n])
, Loop is parallelizable
Accelerator kernel generated
Generating Tesla code
, #pragma acc loop gang, vector(128) /* blockIdx.x threadIdx.x */
, Generating implicit reduction(+:sum)
waxpby(double, const vector &, double, const vector &, const vector &):
, include "vector_functions.h"
, Generating copyin(xcoefs[:x->n])
Generating copy(ycoefs[:y->n],wcoefs[:w->n])
, Loop is parallelizable
Accelerator kernel generated
Generating Tesla code
, #pragma acc loop gang, vector(128) /* blockIdx.x threadIdx.x */
allocate_3d_poission_matrix(matrix &, int):
, include "matrix.h"
, Loop not fused: different loop trip count
, Loop not vectorized/parallelized: loop count too small
, Loop not fused: function call before adjacent loop
, Loop not vectorized: data dependency
, Accelerator clause: upper bound for dimension of array 'A' is unknown
Generating enter data copyin(A[:],A->row_offsets[:num_rows+],A->coefs[:nnz],A->cols[:nnz])
free_matrix(matrix &):
, include "matrix.h"
, Generating exit data delete(A->coefs[:],A->cols[:],A[:],A->row_offsets[:])
matvec(const matrix &, const vector &, const vector &):
, include "matrix_functions.h"
, Generating copyin(Acoefs[:A->nnz])
Generating implicit copyin(row_offsets[:num_rows+])
Generating copyin(xcoefs[:x->n])
Generating implicit copyout(ycoefs[:num_rows])
Generating copyin(cols[:A->nnz])
, Loop is parallelizable
Accelerator kernel generated
Generating Tesla code
, #pragma acc loop gang, worker(8) /* blockIdx.x threadIdx.y */
, #pragma acc loop vector(32) /* threadIdx.x */
, Generating implicit reduction(+:sum)
, Loop is parallelizable
main:
, Loop not vectorized/parallelized: potential early exits
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/cpp$ ./a.out
Rows: , nnz:
Iteration: , Tolerance: 4.0067e+08
Iteration: , Tolerance: 1.8772e+07
Iteration: , Tolerance: 6.4359e+05
Iteration: , Tolerance: 2.3202e+04
Iteration: , Tolerance: 8.3565e+02
Iteration: , Tolerance: 3.0039e+01
Iteration: , Tolerance: 1.0764e+00
Iteration: , Tolerance: 3.8360e-02
Iteration: , Tolerance: 1.3515e-03
Iteration: , Tolerance: 4.6209e-05
Iterarion: , error: 1.993399e-06, time: 3249.523926 ms

● 对应的 fortran 代码优化前后的结果

// Ubuntu 优化前:
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/f90/-multicore$ pgf90 -c matrix.F90 vector.F90
matrix.F90:
vector.F90:
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/f90/-multicore$ pgf90 main.F90 matrix.o vector.o -fast -mp -Minfo -o no_acc.exe
main.F90:
main:
, Loop not vectorized/parallelized: potential early exits
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/f90/-multicore$ ./no_acc.exe
Rows: nnz:
Iteration: Tolerance: 4.006700E+08
Iteration: Tolerance: 1.877230E+07
^C
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/f90/-multicore$ cd ..
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/f90$ pgf90 -c matrix.F90 vector.F90 -fast -Minfo
matrix.F90:
allocate_3d_poisson_matrix:
, Loop not fused: different loop trip count
, Loop not vectorized/parallelized: loop count too small
, Loop unrolled times (completely unrolled)
, Loop not vectorized: data dependency
matvec:
, Loop unrolled times
FMA (fused multiply-add) instruction(s) generated
vector.F90:
initialize_vector:
, Memory set idiom, loop replaced by call to __c_mset8
dot:
, Generated an alternate version of the loop
Generated vector simd code for the loop containing reductions
Generated prefetch instructions for the loop
Generated vector simd code for the loop containing reductions
Generated prefetch instructions for the loop
FMA (fused multiply-add) instruction(s) generated
waxpby:
, Generated alternate versions of the loop
Generated vector simd code for the loop
Generated prefetch instructions for the loop
Generated vector simd code for the loop
Generated prefetch instructions for the loop
Generated vector simd code for the loop
Generated prefetch instructions for the loop
FMA (fused multiply-add) instruction(s) generated
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/f90$ pgf90 main.F90 matrix.o vector.o -fast -Minfo -mp -o no_acc.exe
main.F90:
main:
, Loop not vectorized/parallelized: potential early exits
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/f90$ ./no_acc.exe
Rows: nnz:
Iteration: Tolerance: 4.006700E+08
Iteration: Tolerance: 1.877230E+07
Iteration: Tolerance: 6.435887E+05
Iteration: Tolerance: 2.320219E+04
Iteration: Tolerance: 8.356487E+02
Iteration: Tolerance: 3.003893E+01
Iteration: Tolerance: 1.076441E+00
Iteration: Tolerance: 3.836034E-02
Iteration: Tolerance: 1.351503E-03
Iteration: Tolerance: 4.620883E-05
Total Iterations: Time (s): 23.30484 s // Ubuntu 优化后:
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/f90/-multicore$ pgf90 -c matrix.F90 vector.F90 -acc -fast -Minfo
matrix.F90:
allocate_3d_poisson_matrix:
, Loop not fused: different loop trip count
, Loop not vectorized/parallelized: loop count too small
, Loop unrolled times (completely unrolled)
, Loop not fused: function call before adjacent loop
, Loop not vectorized: data dependency
, Generating enter data copyin(a)
, Generating enter data copyin(a%coefs(:),a%row_offsets(:),a%cols(:))
free_matrix:
, Generating exit data delete(a%coefs(:),a%cols(:),a%row_offsets(:))
, Generating exit data delete(a)
matvec:
, Generating implicit copyin(arow_offsets(:a%num_rows+),acols(:),acoefs(:))
Generating implicit copyout(y(:a%num_rows))
Generating implicit copyin(x(:))
, Loop is parallelizable
Accelerator kernel generated
Generating Tesla code
, !$acc loop gang, worker() ! blockidx%x threadidx%y
, !$acc loop vector() ! threadidx%x
, Generating implicit reduction(+:tmpsum)
, Loop not fused: no successor loop
, Loop is parallelizable
Loop unrolled times
FMA (fused multiply-add) instruction(s) generated
vector.F90:
initialize_vector:
, Generating present(vector(:))
, Loop is parallelizable
Accelerator kernel generated
Generating Tesla code
, !$acc loop gang, vector() ! blockidx%x threadidx%x
, Memory set idiom, loop replaced by call to __c_mset8
allocate_vector:
, Generating enter data create(vector(:))
free_vector:
, Generating exit data delete(vector(:))
dot:
, Generating implicit copyin(y(:length),x(:length))
, Loop is parallelizable
Accelerator kernel generated
Generating Tesla code
, !$acc loop gang, vector() ! blockidx%x threadidx%x
, Generating implicit reduction(+:tmpsum)
, Loop not fused: no successor loop
Generated an alternate version of the loop
Generated vector simd code for the loop containing reductions
Generated prefetch instructions for the loop
Generated vector simd code for the loop containing reductions
Generated prefetch instructions for the loop
FMA (fused multiply-add) instruction(s) generated
waxpby:
, Generating implicit copyin(x(:length),y(:length))
Generating implicit copyout(w(:length))
, Loop is parallelizable
Accelerator kernel generated
Generating Tesla code
, !$acc loop gang, vector() ! blockidx%x threadidx%x
, Loop not fused: no successor loop
Generated alternate versions of the loop
Generated vector simd code for the loop
Generated prefetch instructions for the loop
Generated vector simd code for the loop
Generated prefetch instructions for the loop
Generated vector simd code for the loop
Generated prefetch instructions for the loop
FMA (fused multiply-add) instruction(s) generated
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/f90/-multicore$ pgf90 main.F90 matrix.o vector.o -acc -fast -Minfo -mp -o acc.exe
main.F90:
main:
, Loop not vectorized/parallelized: potential early exits
cuan@CUAN:/media/cuan/02FCDA52FCDA4019/Code/ParallelProgrammingWithOpenACC-master/Chapter02/f90/-multicore$ ./acc.exe
Rows: nnz:
Iteration: Tolerance: 4.006700E+08
Iteration: Tolerance: 1.877230E+07
Iteration: Tolerance: 6.435887E+05
Iteration: Tolerance: 2.320219E+04
Iteration: Tolerance: 8.356487E+02
Iteration: Tolerance: 3.003893E+01
Iteration: Tolerance: 1.076441E+00
Iteration: Tolerance: 3.836034E-02
Iteration: Tolerance: 1.351503E-03
Iteration: Tolerance: 4.620883E-05
Total Iterations: Time (s): 3.533652 s

● C++ 优化结果在 nvprof 中的表现

OpenACC 梯度下降法求解线性方程的优化的更多相关文章

  1. 使用matlab用优化后的梯度下降法求解达最小值时参数

    matlab可以用 -Conjugate gradient -BFGS -L-BFGS 等优化后的梯度方法来求解优化问题.当feature过多时,最小二乘计算复杂度过高(O(n**3)),此时 这一些 ...

  2. 梯度下降法求解函数极大值-Matlab

    目录 目录题目作答1. 建立函数文件ceshi.m2. 这是调用的命令,也可以写在.m文件里3. 输出结果题外话 题目 作答 本文使用MATLAB作答 1. 建立函数文件ceshi.m functio ...

  3. 机器学习---用python实现最小二乘线性回归算法并用随机梯度下降法求解 (Machine Learning Least Squares Linear Regression Application SGD)

    在<机器学习---线性回归(Machine Learning Linear Regression)>一文中,我们主要介绍了最小二乘线性回归算法以及简单地介绍了梯度下降法.现在,让我们来实践 ...

  4. tensorflow实现svm多分类 iris 3分类——本质上在使用梯度下降法求解线性回归(loss是定制的而已)

    # Multi-class (Nonlinear) SVM Example # # This function wll illustrate how to # implement the gaussi ...

  5. tensorflow实现svm iris二分类——本质上在使用梯度下降法求解线性回归(loss是定制的而已)

    iris二分类 # Linear Support Vector Machine: Soft Margin # ---------------------------------- # # This f ...

  6. 梯度下降法原理与python实现

    梯度下降法(Gradient descent)是一个一阶最优化算法,通常也称为最速下降法. 要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离 ...

  7. 梯度下降法(BGD、SGD)、牛顿法、拟牛顿法(DFP、BFGS)、共轭梯度法

    一.梯度下降法 梯度:如果函数是一维的变量,则梯度就是导数的方向:      如果是大于一维的,梯度就是在这个点的法向量,并指向数值更高的等值线,这就是为什么求最小值的时候要用负梯度 梯度下降法(Gr ...

  8. 理解梯度下降法(Gradient Decent)

    1. 什么是梯度下降法?   梯度下降法(Gradient Decent)是一种常用的最优化方法,是求解无约束问题最古老也是最常用的方法之一.也被称之为最速下降法.梯度下降法在机器学习中十分常见,多用 ...

  9. matlib实现梯度下降法

    样本文件下载:ex2Data.zip ex2x.dat文件中是一些2-8岁孩子的年龄. ex2y.dat文件中是这些孩子相对应的体重. 我们尝试用批量梯度下降法,随机梯度下降法和小批量梯度下降法来对这 ...

随机推荐

  1. 51Nod - 1001:数组中和等于K的数对

    基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 给出一个整数K和一个无序数组A,A的元素为N个互不相同的整数,找出数组A中所有和等于K的数对.例如K = 8,数组A: ...

  2. 51Nod:活动安排问题(区间问题)

    X轴上有N条线段,每条线段有1个起点S和终点E.最多能够选出多少条互不重叠的线段.(注:起点或终点重叠,不算重叠). 例如:[1 5][2 3][3 6],可以选[2 3][3 6],这2条线段互不重 ...

  3. JQuery输入框获取/失去焦点行为

    //搜索框获取焦点清除内容 $(function() { $("input").focus(function() { //获取焦点,清空默认内容 $(this).css('colo ...

  4. java类库 java API jar包 C语言函数库

    翁凯说:java的强大是因为类库的强大 C/C++强大是因为函数库 在程序中用到系统提供的标准函数库中的输入输出函数时 应在程序的开头写上一行:#include"stdio.h"或 ...

  5. apache flink kubernetes 运行试用

    类似docker-compose 运行模式,使用的是deploy 的模式 deploy yaml 文件 deploy-k8s-yaml apiVersion: extensions/v1beta1 k ...

  6. Erlang

    Erlang The Erlang BEAM Virtual Machine Specificationhttp://www.cs-lab.org/historical_beam_instructio ...

  7. lamba数据架构以及数据湖

    面试大数据项目,面试过程中发现面试官提到的两个概念没有搞清楚: 1. lamba数据架构:这个概念的提出是由storm的作者提出来的,其实主旨就是想要说明,数据的处理分成三层,一类是批处理程序(bat ...

  8. golang panic的捕获

    panic发生时, 会导致进程挂掉.为了处理panic, 可以使用recover捕获,然后处理. 下面以下标引用越界问题为例进行说明. 正常情况下,代码中如果出现下标越界,会直接触发panic, 导致 ...

  9. openwrt设置默认登陆密码

    1.修改dropbear配置文件 找到package/network/services/dropbear/files/dropbear.config 修改如下: config dropbear opt ...

  10. 重置SQL Server sa密码

    查询分析器,连接时,身份验证使用"使用windows身份验证" 然后,执行: EXEC sp_password NULL, '新密码', 'Sa'