OpenMP核心技术指南学习笔记:
*.设置并行线程数
omp_set_num_threads(num);
*.获取线程数量
int omp_get_num_threads();
*.获取线程ID
int omp_get_thread_num();
*.omp墙钟计时器
double omp_get_wtime();
SPMD设计模式:单程序多数据设计模式
1)启动两个或多个执行相同代码的线程;
2)每个线程确定其ID和线程组中的线程数;
3)根据ID和线程组中的线程数和线程之间的分配工作;
举例:此处使用二维矩阵的sum,是为了消除伪共享中的高速缓存行在核心之间来回移动产生的开销;
如果是一维矩阵sum的话,效率降低一半。
#include <iostream>
#include <thread>
#include <omp.h>
#define NTHREADS 4
#define CBLK 8
using namespace std;
static long num_steps=100000000;
void main()
{
int i, j, actual_nthreads;
double stime, runtime;
double sum[NTHREADS][CBLK] = {0};
double step = 1.0 / num_steps;
omp_set_num_threads(NTHREADS);
stime = omp_get_wtime();
//周期分布划分
#pragma omp parallel
{
int i;
int id = omp_get_thread_num(); //线程ID
int numthreads = omp_get_num_threads(); //线程总数
double x;
if (id == 0)
{
actual_nthreads = numthreads;
}
for (i = id; i<num_steps; i+=numthreads)
{
x = (i + 0.5) * step;
sum[id][0] += 4.0 / (1.0 + x * x);
}
}
//块状分解划分
//#pragma omp parallel
// {
// int i;
// int id = omp_get_thread_num();
// int numthreads = omp_get_num_threads();
// double x;
// actual_nthreads = numthreads;
// int ista = id * num_steps / NTHREADS;
// int iend = (id + 1) * num_steps / NTHREADS;
// for ( i = ista; i < iend; i++)
// {
// x = (i + 0.5) * step;
// sum[id] += 4.0 / (1.0 + x * x);
// }
// }
double pi = 0.0;
for (int i = 0; i < actual_nthreads; i++)
{
pi += sum[i][0];
}
pi *= step;
runtime = omp_get_wtime() - stime;
cout << "pi=" << pi << endl;
cout << "cost time:" << runtime<<endl;
system("pause");
}
}