▶ 书上第二章,用一系列步骤优化梯度下降法解线性方程组。才发现 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. HDU 1233:还是畅通工程(最小生成树)

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  2. 51Nod:1268 和为K的组合

    1268 和为K的组合  基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 给出N个正整数组成的数组A,求能否从中选出若干个,使他们的和为K.如果可以 ...

  3. Linux修改开机启动logo

    默认开机LOGO会在液晶屏的左上脚显示一只小企鹅,分辨率为80*80,具体在kernel/drivers/video/logo下会有logo_linux_clut224.ppm这幅图像,程序会根据这幅 ...

  4. 我的nginx iis 负载均衡学习(环境搭建)

    1,下载并安装nginx 比较简单 2,进行网站的配置 我使用了我的IIS 站点中已经拥有的两个站点 3,进行nginx 的配置 配置如下: 在server 节点之前添加如下的配置: upstream ...

  5. Linux下载

    免费下载地址在 http://linux.linuxidc.com/ 用户名与密码都是www.linuxidc.com 下载方法见 http://www.linuxidc.com/Linux/2013 ...

  6. Mfs+drbd+keepalived实现mfs系统高可用

    http://blog.sina.com.cn/s/blog_53c654720102wo1k.html Moosefs分布式文件系统是一个易用的系统,但其只有在Pro版中提供了master的高可用方 ...

  7. centos 使用mutt发送邮件带附件

    1.安装mutt工具 yum install -y mutt 2.使用mutt发邮件并带附件echo "统计日志" | /usr/bin/mutt -s "统计日志&qu ...

  8. MapReduce-皮尔逊(Pearson)线性相关

    Pearson相关系数解决了两个群的数据是否线性相关的问题: 先补充一下基本概念: 协方差:如果两个变量的变化趋势一致,也就是说如果其中一个大于自身的期望值时另外一个也大于自身的期望值,那么两个变量之 ...

  9. Decision_function:scores,predict以及其他

    机器学习的评估 PR曲线用于positive类数据占比比较小,或者你更加在意false postion(相比于false negative):其他情况采用ROC曲线:比如Demo中手写体5的判断,因为 ...

  10. jQuery如何取得HiddenField值(转)

    <f:HiddenField runat="server" ID="cat_id" Text="ssss"/> var strD ...