gpt4 book ai didi

c - OMP C 中的嵌套 for 循环

转载 作者:太空宇宙 更新时间:2023-11-04 08:53:57 26 4
gpt4 key购买 nike

我有一个程序可以将作为字符 vector 提供的 2 个大数相乘。现在我必须确保它使用 OpenMP。我有嵌套循环的问题,如果我使用它们,结果不是我所期望的。非常感谢您的帮助。这是代码

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#include<omp.h>
#include<time.h>
#define MAX 100000

char * multiply(char [],char[], int manyThreads);
int main(){
//omp_set_dynamic(1);
omp_set_nested(1);
omp_set_num_threads(8);
char a[MAX];
char b[MAX];
char *c;

printf("First number : ");
scanf("%s",a);
printf("Second number : ");
scanf("%s",b);
printf("Result : ");
double start = omp_get_wtime( );

c = multiply(a,b,1);
printf("%s\n",c);
double end = omp_get_wtime( );
printf("Calculation time = %.16g\n", end - start);

return 0;
}

char * multiply(char a[],char b[], int manyThreads){
static char result[MAX];
char tempResult[MAX];
char temp[MAX];
int aLength,bLength;
int i,j,k=0,x=0,y;
long int r=0;
long sum = 0;
aLength=strlen(a)-1;
bLength=strlen(b)-1;

#pragma omp parallel if(manyThreads == 1)
{
#pragma omp for schedule(dynamic) nowait
for(i=0;i<=aLength;i++)
{
a[i] = a[i] - 48;
}

#pragma omp for schedule(dynamic) nowait
for(i=0;i<=bLength;i++)
{
b[i] = b[i] - 48;
}
}

#pragma omp parallel if(manyThreads == 1)
{
#pragma omp for schedule(dynamic)
for(i=bLength;i>=0;i--)
{
r=0;

#pragma omp parallel
{
#pragma omp for schedule(dynamic)
for(j=aLength;j>=0;j--)
{
temp[k++] = (b[i]*a[j] + r)%10;
r = (b[i]*a[j]+r)/10;
}
}
temp[k++] = r;
x++;
#pragma omp parallel
{
#pragma omp for schedule(dynamic)
for(y = 0;y<x;y++)
{
temp[k++] = 0;
}
}
}
}

k=0;
r=0;
#pragma omp parallel if(manyThreads == 1)
{
#pragma omp for schedule(dynamic)
for(i=0;i<aLength+bLength+2;i++)
{
sum =0;
y=0;
#pragma omp parallel
{
#pragma omp for schedule(dynamic)
for(j=1;j<=bLength+1;j++)
{
if(i <= aLength+j)
{
sum = sum + temp[y+i];
}
y += j + aLength + 1;
}
}

tempResult[k++] = (sum+r) %10;
r = (sum+r)/10;
}
}
tempResult[k] = r;
j=0;

#pragma omp parallel if(manyThreads == 1)
{
#pragma omp for schedule(dynamic)
for(i=k-1;i>=0;i--)
{
result[j++]=tempResult[i] + 48;
}
}

result[j]='\0';

if(result[0]==48)
{
result[0]=255;
}

return result;
}

最佳答案

我可以确认,你有一些数据竞争错误。
没有 OpenMP:

First number : 123456
Second number : 654321
Result :  08563613376
Calculation time = 0.005543371655221563

使用 OpenMP:

First number : 123456
Second number : 654321
Result :  00000000825
Calculation time = 0.007188999978097854

我并没有解决整个问题,但根据我所看到的,我有一些评论。
首先我会说你应该在 for 构造中指定 for 变量

#pragma omp for schedule(dynamic) nowait
for(int i=0;i<=aLength;i++)
{
a[i] = a[i] - 48;
}

以及您(每次)犯下的主要错误的示例……当您进入平行区域时,您必须注意您的变量。什么是共享的,什么是每个线程私有(private)的?在你的结束循环中,你不使用嵌套并行性,但你在每个线程中执行了一个j++,所以你应该像下面这样保护 j。

#pragma omp parallel if(manyThreads == 1) shared(j) 
{
int pos;
#pragma omp for schedule(dynamic)
for(int i=k-1;i>=0;i--)
{
#pragma omp atomic capture
pos = j++;

result[pos]=(tempResult[i] + 48);
}
}

请注意,您还忘记了 OpenMP for 构造具有 reduction 子句

所以你计算 sum += temp[y+i] 的 for 循环可以用

重写
#pragma omp for schedule(dynamic) reduction(+:sum)

并且您必须遵循所有算法逻辑,以在每个周围和嵌套的 parallel 区域上使用 sharedprivate 子句。

关于c - OMP C 中的嵌套 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18299693/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com