C++ C++;矩阵乘法器
当我在使用GCC编译的过程中启用OpenACC时,我的代码速度较慢有什么原因吗?我目前正在Windows10上使用GCC6.3.0。我真的不知道为什么会这样 这是我正在编译的命令:C++ C++;矩阵乘法器,c++,gcc,parallel-processing,matrix-multiplication,openacc,C++,Gcc,Parallel Processing,Matrix Multiplication,Openacc,当我在使用GCC编译的过程中启用OpenACC时,我的代码速度较慢有什么原因吗?我目前正在Windows10上使用GCC6.3.0。我真的不知道为什么会这样 这是我正在编译的命令:g++-fopenacc-oaexample.cpp 这里是我的C++代码: #include <stdlib.h> #include <cassert> #include <chrono> double *A, *B, *C; int main(int argc, char
g++-fopenacc-oaexample.cpp
这里是我的C++代码:
#include <stdlib.h>
#include <cassert>
#include <chrono>
double *A, *B, *C;
int main(int argc, char* argv[]) {
long long N = 100;
A = new double[N * N];
B = new double[N * N];
C = new double[N * N];
srand(42);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
A[i * N + j] = rand();
B[i * N + j] = rand();
}
}
for (int x = 0; x < 10; x++) {
auto start_time = std::chrono::high_resolution_clock::now();
#pragma acc kernels
{
#pragma acc loop independent
for (int i = 0; i < N; i++) {
#pragma acc loop independent
for (int j = 0; j < N; j++) {
double total = 0;
#pragma acc loop independent reduction (+: total)
for (int k = 0; k < N; k++) {
total += A[i * N + j] * B[k * N + j];
}
C[i * N + j] = total;
}
}
}
auto end_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> duration = end_time - start_time;
printf("%f seconds\n", duration.count());
}
return 0;
}
#包括
#包括
#包括
双*A、*B、*C;
int main(int argc,char*argv[]){
长N=100;
A=新的双精度[N*N];
B=新的双精度[N*N];
C=新的双精度[N*N];
srand(42);
对于(int i=0;i
不确定GNU 6.3是否支持OpenACC,至少不太支持,我也不知道Windows是否支持OpenACC。我在Linux上使用GNU10.2,在Linux上OpenACC支持更好
然而,GNU仍然不能很好地处理“kernels”指令,因此我建议使用parallel。此外,您还缺少一个数据区域,因此如果卸载此代码,则会出现运行时错误
例如:
% g++ --version
g++ (GCC) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
%
% cat mm.cpp
#include <stdlib.h>
#include <stdio.h>
#include <cassert>
#include <chrono>
#ifdef USE_PARALLEL
#define ACC_TYPE parallel
#else
#define ACC_TYPE kernels
#endif
double *A, *B, *C;
int main(int argc, char* argv[]) {
long long N = 100;
A = new double[N * N];
B = new double[N * N];
C = new double[N * N];
srand(42);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
A[i * N + j] = rand();
B[i * N + j] = rand();
}
}
#pragma acc data copyin(A[:N*N],B[:N*N]) copyout(C[:N*N])
for (int x = 0; x < 10; x++) {
auto start_time = std::chrono::high_resolution_clock::now();
#pragma acc ACC_TYPE
{
#pragma acc loop independent
for (int i = 0; i < N; i++) {
#pragma acc loop independent
for (int j = 0; j < N; j++) {
double total = 0;
#pragma acc loop independent reduction (+: total)
for (int k = 0; k < N; k++) {
total += A[i * N + j] * B[k * N + j];
}
C[i * N + j] = total;
}
}
}
auto end_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> duration = end_time - start_time;
printf("%f seconds\n", duration.count());
}
return 0;
}
% g++ -fopenacc mm.cpp -Ofast ; a.out
0.020057 seconds
0.020025 seconds
0.020022 seconds
0.020021 seconds
0.019538 seconds
0.018271 seconds
0.018270 seconds
0.018264 seconds
0.018274 seconds
0.018270 seconds
% g++ -fopenacc mm.cpp -Ofast -DUSE_PARALLEL ; a.out
0.000123 seconds
0.000086 seconds
0.000081 seconds
0.000078 seconds
0.000078 seconds
0.000077 seconds
0.000077 seconds
0.000076 seconds
0.000076 seconds
0.000076 seconds
%g++--版本
g++(GCC)10.2.0
版权所有(C)2020免费软件基金会。
这是自由软件;有关复制条件,请参见源。没有
担保甚至不是为了适销性或适合某一特定目的。
%
%cat mm.cpp
#包括
#包括
#包括
#包括
#ifdef使用_并行
#定义ACC_类型并行
#否则
#定义ACC_类型内核
#恩迪夫
双*A、*B、*C;
int main(int argc,char*argv[]){
长N=100;
A=新的双精度[N*N];
B=新的双精度[N*N];
C=新的双精度[N*N];
srand(42);
对于(int i=0;i
不确定GNU 6.3是否支持OpenACC,至少不太支持,我也不知道Windows是否支持OpenACC。我在Linux上使用GNU10.2,在Linux上OpenACC支持更好
然而,GNU仍然不能很好地处理“kernels”指令,因此我建议使用parallel。此外,您还缺少一个数据区域,因此如果卸载此代码,则会出现运行时错误
例如:
% g++ --version
g++ (GCC) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
%
% cat mm.cpp
#include <stdlib.h>
#include <stdio.h>
#include <cassert>
#include <chrono>
#ifdef USE_PARALLEL
#define ACC_TYPE parallel
#else
#define ACC_TYPE kernels
#endif
double *A, *B, *C;
int main(int argc, char* argv[]) {
long long N = 100;
A = new double[N * N];
B = new double[N * N];
C = new double[N * N];
srand(42);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
A[i * N + j] = rand();
B[i * N + j] = rand();
}
}
#pragma acc data copyin(A[:N*N],B[:N*N]) copyout(C[:N*N])
for (int x = 0; x < 10; x++) {
auto start_time = std::chrono::high_resolution_clock::now();
#pragma acc ACC_TYPE
{
#pragma acc loop independent
for (int i = 0; i < N; i++) {
#pragma acc loop independent
for (int j = 0; j < N; j++) {
double total = 0;
#pragma acc loop independent reduction (+: total)
for (int k = 0; k < N; k++) {
total += A[i * N + j] * B[k * N + j];
}
C[i * N + j] = total;
}
}
}
auto end_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> duration = end_time - start_time;
printf("%f seconds\n", duration.count());
}
return 0;
}
% g++ -fopenacc mm.cpp -Ofast ; a.out
0.020057 seconds
0.020025 seconds
0.020022 seconds
0.020021 seconds
0.019538 seconds
0.018271 seconds
0.018270 seconds
0.018264 seconds
0.018274 seconds
0.018270 seconds
% g++ -fopenacc mm.cpp -Ofast -DUSE_PARALLEL ; a.out
0.000123 seconds
0.000086 seconds
0.000081 seconds
0.000078 seconds
0.000078 seconds
0.000077 seconds
0.000077 seconds
0.000076 seconds
0.000076 seconds
0.000076 seconds
%g++--版本
g++(GCC)10.2.0
版权所有(C)2020免费软件基金会。
这是自由软件;有关复制条件,请参见源。没有
担保甚至不是为了适销性或适合某一特定目的。
%
%cat mm.cpp
#包括
#包括
#包括
#包括
#ifdef使用_并行
#定义ACC_类型并行
#否则
#定义ACC_类型内核
#恩迪夫
双*A、*B、*C;
int main(int argc,char*argv[]){
长N=100;
A=新的双精度[N*N];
B=新的双精度[N*N];
C=新的双精度[N*N];
srand(42);
对于(int i=0;i