我需要使用带有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操作不成功。 怎么解决?谢谢!
答案 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);
}
}