OpenMP梯度积分法
1.梯度积分法
2.识别两类任务
- 单个梯形的面积计算
- 梯形面积求和
在2.1的任务中,没有任务间的通信,但这一组任务中的每一组任务都与2.2的任务通信
3.累加线程结果
使用一个共享变量作为所有线程的和 ,每个线程可以将它计算的部分结果累加到共享变量中,让每个线程执行类似下面的语句:
| #pragma omp critical global_result += myresult;
|
竞争条件,使用临界区解决。保证每次只有一个线程执行这段结构性代码。
4.程序完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #include <stdio.h> #include <stdlib.h> #include <omp.h>
void Trap(double a,double b,int n,double *global_result_p); int main(int argc, char *argv[]){ double global_result = 0.0; double a,b; int n; int thread_count; thread_count = 8; printf("Enter a,b, and n\n"); scanf("%lf %lf %d",&a,&b,&n); #pragma omp parallel num_threads(thread_count) Trap(a,b,n,&global_result); printf("With n = %d trapezoids, our estimate\n",n); printf("of the integral from %f to %f = %.4lf\n",a,b,global_result); return 0; } void Trap(double a,double b,int n,double *global_result_p) { double h,x,my_result; double local_a,local_b; int i,local_n; int my_rank = omp_get_thread_num(); int thread_count = omp_get_num_threads(); h = (b-a)/n; local_n = n/thread_count; local_a = a + my_rank*local_n*h; local_b = local_a + local_n*h; my_result = (f(local_a) + f(local_b))/2.0; for(i = 1 ; i<=local_n-1; i++){ x = local_a + i*h; my_result += f(x); } my_result = my_result*h; #pragma omp critical *global_result_p += my_result; }
|
5.总结
- 核心是拆分任务区域,把子任务分配到个个线程
- 共享变量的选取决定了可并行度
- 通过共享变量实现了归约的操作(这里使用到了临界区)
6.参考资料
并行程序导论 (美)Peter S.Pacheco