C++ C++;矩阵乘法器

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

当我在使用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* 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