使用OpenMP和mpz_t malloc会导致分段错误

时间:2014-02-24 11:30:24

标签: c openmp gmp

我需要使用带有2 ^ 15大小的mpz_t数组的OpenMP编程来并行以下代码:

#pragma omp parallel for private(j,temp3)
for(j=Real;j<LL;j++)//l
    {
        for(__int64_t k=0;k<=((j/(Real*1.0))/(log(sieve[i])/log(2.0)));k++)//l5
        {
            if((((j/(Real*1.0)-k*(log(sieve[i])/log(2.0)))<LL))&&(((j/(Real*1.0)-k*(log(sieve[i])/log(2.0)))>0)))// can log() use __int64_t?
                mpz_add(temp3[j],temp3[j],temp2[(int)floor((j-k*Real*(log(sieve[i])/log(2.0))))]);
        }
        mpz_add_ui(temp3[j],temp3[j],(int)floor(((j/(Real*1.0))/(log(sieve[i])/log(2.0)))));
    }

我像这样初始化数组temp3:

mpz_t temp3[LL];

它会导致分段错误。所以我试着这样写:

mpz_t *temp3=(mpz_t *)malloc(sizeof(mpz_t)*LL);

它还会导致分段错误,并且malloc操作不成功。 怎么解决?谢谢!

1 个答案:

答案 0 :(得分:0)

当temp3是一个数组(mpz_t temp3[ll])并且您将其声明为私有时,OpenMP会为每个线程生成该数组的私有版本(即,它从每个线程的堆栈中分配单独的私有内存)。但是,在第二种情况下,使用malloc temp3只是一个指针(数组和指针不是同一个东西),当你传递一个私有指针时,OpenMP只为每个线程创建指针的私有版本(它不分配记忆)。

在第一种情况下,崩溃可能是由于数组大于堆栈大小。在第二种情况下,指针的私有版本永远不会被初始化(因为它们将与firstprivate一起使用),因此它们指向可能导致崩溃的未知内存地址。

解决方案很简单。 不要声明temp3私有。应该分享。

如果你使用firstprivate,你可以尝试将temp3保留为私有,但我认为这不是一个好主意。

#include <stdio.h>
#include <stdlib.h>
int main() {
    int x[10];
    printf("%p\n", x);
    #pragma omp parallel private(x) 
    {
        printf("%p\n", x);
    }

    int* y = (int*)malloc(10*sizeof(int));
    #pragma omp parallel firstprivate(y)
    {
        printf("%p\n", y);
    }
}