c++ - OpenMP 代码中止

标签 c++ c++11 openmp

我正在尝试使用 openMP 执行矩阵乘法,如下所示,我使用 GCC 编译它:g++ -std=gnu++11 -g -Wall -fopenmp -o parallel_not_opt parallel_not_opt.cpp

但是当我尝试使用 parallel_not_opt.exe 运行它时,它会中止并显示典型的 Windows 错误 parallel_not_opt.exe 已停止工作...

我错过了什么吗?

#include "includes/stdafx.h"

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <vector>
# include <omp.h>
#include <chrono>
#include <fstream>
#include <algorithm>
#include <immintrin.h>
#include <cfloat>
#include <limits>
#include <math.h>

using namespace std::chrono;
using namespace std;


//populate matrix with random values.
double** generateMatrix(int n){ 
    double max = DBL_MAX;
    double min = DBL_MIN;
    double** matA = new double*[n];
    for (int i = 0; i < n; i++) {
        matA[i] = new double[n];
        for (int j = 0; j < n; j++) {
            double randVal = (double)rand() / RAND_MAX;
            matA[i][j] = min + randVal * (max - min);
        }
    }
    return matA;
}

//generate matrix for final result.
double** generateMatrixFinal(int n){ 
    double** matA = new double*[n];
    for (int i = 0; i < n; i++) {
        matA[i] = new double[n];
        for (int j = 0; j < n; j++) {
            matA[i][j] = 0;
        }
    }
    return matA;
}

//matrix multiplication - parallel
double matrixMultiplicationParallel(double** A, double** B, double** C, int n){
    int i, j, k;
    clock_t begin_time = clock(); 
# pragma omp parallel shared ( A,B,C,n  ) // private ( i, j, k )
    {
# pragma omp for
        for (i = 0; i < n; i++) {
            //            cout<< i << ", " ;
            for (j = 0; j < n; j++) {
                for (k = 0; k < n; k++) {
                    C[i][j] += A[i][k] * B[k][j];
                }
            }
        }
    } 
    double t = float(clock() - begin_time); 
    return t;
}

int _tmain(int argc, _TCHAR* argv[])
{

    ofstream out("output.txt", ios::out | ios::app);
    out << "--------------STARTED--------------" << "\n";
    int start = 200, stop = 2000, step = 200;

    for (int n = start; n <= stop; n += step)
    {

        srand(time(NULL));
        cout << "\nn: " << n << "\n"; 
        double t1 = 0;

        int my_size = n; 
        double **A = generateMatrix(my_size); 
        double **B = generateMatrix(my_size); 
        double **C = generateMatrixFinal(my_size); 
        double single_sample_time = matrixMultiplicationParallel(A, B, C, n);     
        t1 += single_sample_time;
        for (int i = 0; i < n; i++) {
            delete[] A[i];
            delete[] B[i];
            delete[] C[i];
        }
        delete[] A;
        delete[] B;
        delete[] C;         
    }
    out << "-----------FINISHED-----------------" << "\n";
    out.close();
    return 0;
}

最佳答案

private ( i, j, k ) 声明不是可选的。加回去,否则内层循环变量jk是共享的,这样就彻底把内层循环搞乱了。

最好尽可能在本地声明变量。这使得对 OpenMP 代码的推理变得更加容易:

clock_t begin_time = clock(); 
# pragma omp parallel
{
# pragma omp for
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
} 
return float(clock() - begin_time); 

在这种情况下,A,B,C 将默认共享 - 来自外部,而 j,k 是私有(private)的,因为它们是在并行中声明的范围。 parallel for 的循环变量始终隐式私有(private)。

关于c++ - OpenMP 代码中止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45014794/

相关文章:

c++ - 指针和数组地址

c++ - MFC .dll,CString问题,IDA c++伪代码,有多接近?

c++ - 不定义函数的基本模板案例是常见的做法吗?

c++ - static_assert 中的 std::pow 触发错误 C2057?

c++ - "char[]"是正确的类型吗?

c++ - 无法将多个初始化列表传递给可变参数函数模板

c++ - 为什么 pthread_key_create 析构函数被调用了几次?

c - OpenMP线程,如何正确使用omp原子子句?

c++ - 不同线程数 openMP 上的相同程序执行时间

带有 OpenMP 的安卓系统