04.forthClass
第四节课
制导语句 其他线程跳过master语句,往下执行
progma omp master
pragma omp barrier
pragma omp for
隐式阻断,使用
nowait
跳过pragma omp critical
作用域代码一次只能执行一个线程
pragma omp atomic
原子操作,类似critical,稍微高级一点;允许不相关的两个线程同时操作
pragma omp parallel for
将for循环并行化
redction(+:ave)对for循环中ave变了进行规约
firstprivate(sum) 继承并行区域之外的变量的值,用于在进入并行区域之前进行一次初始化,只是一个拷贝,不会修改并行域之外的值。
lastprivate(sum) 在退出并行区域时,需要将其值赋给同名的共享变量
private 将一个或多个变量声明为线程的私有变量。每个线程都有它自己的变量私有副本,其他线程无法访问;private变量在进入和退出并行区域是“未定义“的。
critical制导语句
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "omp.h"
#define NUM_THREADS 5
#define PAD 8 //跟CPU内存分配有关
double step;
static long num_steps;
int main()
{
clock_t start_t, end_t;
double total_t;
start_t = clock();
num_steps = 100000000;
double pi;
pi=0.0;
step = 1.0 / (double)num_steps; //将1平分成100000步
omp_set_num_threads(NUM_THREADS); //设置要使用的线程数目
#pragma omp parallel //开始并发执行
{
double x,sum;
int id , i;
id = omp_get_thread_num(); //获取每个线程的id编号
sum= 0.0;
for (i=id; i < num_steps; i = i + NUM_THREADS)
{
x = (i - 0.5) * step;
sum += 4.0 / (1.0 + x * x);
}
#pragma omp critical
{
pi+=sum*step;
}
}
end_t = clock();
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
printf("运行时间为%fs\t%f\n", total_t, pi);
return 0;
}
for reduction循环规约
#pragma omp parallel //开始并发执行
{
double x,sum;
int id , i;
id = omp_get_thread_num(); //获取每个线程的id编号
sum= 0.0;
#pragma omp parallel for reduction(+:sum) //for循环规约,多个sum最后会加到最外层的sum
for (i=id; i < num_steps; i = i + NUM_THREADS)
{
x = (i - 0.5) * step;
sum += 4.0 / (1.0 + x * x);
}
pi+=sum*step;
}
for 循环 lastprivate(sum)规约
double sum=0.0;
#pragma omp parallel //开始并发执行
{
double x,sum;
int id , i;
id = omp_get_thread_num(); //获取每个线程的id编号
#pragma omp parallel for lastprivate(sum) //获取每个初始化的sum=0.0
for (i=id; i < num_steps; i = i + NUM_THREADS)
{
x = (i - 0.5) * step;
sum += 4.0 / (1.0 + x * x);
}
//
pi+=sum*step; //这里的sum等于最后一个退出的sum的值,虽然能算出结果,但只是其中一个线程的结果,精度会有所下降
}
for循环 private(sum)规约
#pragma omp parallel //开始并发执行
{
double x,sum=1.0;
int id , i;
id = omp_get_thread_num(); //获取每个线程的id编号
#pragma omp parallel for lastprivate(sum)
for (i=id; i < num_steps; i = i + NUM_THREADS)
{
x = (i - 0.5) * step;
sum += 4.0 / (1.0 + x * x);
}
printf("%f\n",sum);
pi+=sum*step;
}
//最后输出4个1.0
Last updated
Was this helpful?