c-通过控制台设置线程数时出现Openmp分段错误



我有使用openmp:进行矩阵乘法的代码

#include <stdio.h>
#include <omp.h>
#include <math.h>
#define N 1000
int main()
{
    long int i, j, k;
    //long int N = atoi(argv[1]);
    double t1, t2;
    double a[N][N],b[N][N],c[N][N]; 
    for (i=0; i<N; i++)
        for (j=0; j<N; j++)
            a[i][j]=b[i][j]=log(i*j/(i*j+1.)+1) +exp(-(i+j)*(i+j+1.));
    t1=omp_get_wtime();
    #pragma omp parallel for shared(a, b, c) private(i, j, k)
    for(i=0; i<N; i++){
        for(j=0; j<N; j++){
            c[i][j] = 0.0;
            for(k=0; k<N; k++) c[i][j]+=a[i][k]*b[k][j];
        }
    }
    t2=omp_get_wtime();
    printf("Time=%lfn", t2-t1);
}

现在我想通过命令行设置我想要的线程数。我使用

atoi(argv[])

#include <stdio.h>
#include <omp.h>
#include <math.h>
#define N 1000
int main(int argc, char** argv[])
{
    long int i, j, k;
    //long int N = atoi(argv[1]);
    double t1, t2;
    double a[N][N],b[N][N],c[N][N];
    for (i=0; i<N; i++)
        for (j=0; j<N; j++)
            a[i][j]=b[i][j]=log(i*j/(i*j+1.)+1) +exp(-(i+j)*(i+j+1.));
    int t = atoi(argv[1]);
    t1=omp_get_wtime();
    #pragma omp parallel for shared(a, b, c) private(i, j, k) num_threads(t)
    for(i=0; i<N; i++){
        for(j=0; j<N; j++){
            c[i][j] = 0.0;
            for(k=0; k<N; k++) c[i][j]+=a[i][k]*b[k][j];
        }
    }
    t2=omp_get_wtime();
    printf("Time=%lfn", t2-t1);
}

一切都很好,除了一件至关重要的事情:当我试图计算维度大于(或多或少)500的矩阵的乘积时,我会得到错误:"分割错误"。有人能澄清这个错误的原因吗?

我对openmp一无所知,但你肯定会毁掉你的堆栈。默认堆栈空间因系统而异,但使用N == 1000时,您将尝试在堆栈上放置三个总计300万个double的2D阵列。假设一个double是8个字节,那就有2400万个字节,或者只差22.9MB。没有多少系统允许这种堆栈空间。相反,我建议尝试从堆中获取那么多内存。类似这样的东西:

//double a[N][N],b[N][N],c[N][N];
double **a, **b, **c;
a = malloc(sizeof(double*) * N);
b = malloc(sizeof(double*) * N);
c = malloc(sizeof(double*) * N);
for (i=0; i<N; i++)
{
  a[i] = malloc(sizeof(double) * N);
  b[i] = malloc(sizeof(double) * N);
  c[i] = malloc(sizeof(double) * N);
}
// do your calculations
for (i=0; i<N; i++)
{
  free(a[i]);
  free(b[i]);
  free(c[i]);
}
free(a);
free(b);
free(c);

我至少在我的机器上验证过,使用N == 1000,当我试图将这些阵列放置在堆栈上时,我会使用EXC_BAD_ACCESS崩溃。当我按照上面所示的方式动态分配内存时,我不会出现seg错误。

最新更新