OpenMP学习笔记

OpenMP学习笔记

标签(空格分隔): 学习笔记


Hello World程序

#include <iostream>
int main()
{
  #pragma omp parallel
  {
    std::cout << "Hello World!\n";
  }
}

保存之后用-fopenmp参数编译

tintin$ g++ test1.cpp -fopenmp
tintin$ ./a.out 
Hello World!

咦?说好的多线程并行呢?怎么还是只有一句?
别急这是因为你并没有设置并行参数,所以它默认就使用cpu的核心线程数作为参数
而你的虚拟机在设置的时候只吝啬地给了它单核单线程,所以结果和没有并行的正常代码是一样的
你可以给你的虚拟机重新设置过cpu的配置,也可以手动设置参数


调控Openmp的行为

num_threads(编译指示)

#include <iostream>
int main()
{
  /*表示使用5个线程*/
  #pragma omp parallel num_threads(5) 
  {
    std::cout << "Hello World!\n";
  }
}

此时你运行之后的结果当然是5句熟悉的Hello World了


omp_set_num_threads(运行API)

然而如果一个程序中有很多地方需要用到该设置的话,一个一个地去设置效率不高,而且如果要改动也很麻烦,所以我们可以通过另一个函数来着设置全局的线程参数

#include <omp.h>  //需要引入头文件omp.h
#include <iostream>
int main()
{
  omp_set_num_threads(5); 
  #pragma omp parallel 
  {
    std::cout << "Hello World!\n";
  }
}

环境变量来调整(环境变量)

tintin$ export OMP_NUM_THREADS=6
tintin$ ./a.out 
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!

这个时候问题来了,同时使用环境变量和运行时API会出现啥情况呢?
答案是:同时使用环境变量和运行时 API 会出现什么情况?运行时 API 将获得更高的优先权。


一个实例

int main( )
{
int a[1000000], b[1000000]; 
// ... some initialization code for populating arrays a and b; 
int c[1000000];
for (int i = 0; i < 1000000; ++i)
  c[i] = a[i] * b[i] + a[i-1] * b[i+1];
// ... now do some processing with array c
 }

显然,我们可以将 for 循环分为几个部分,在不同的核心中运行它们,任何 c[k] 与 c 数组中的其他元素都是独立的。

int main( )
{
int a[1000000], b[1000000]; 
// ... some initialization code for populating arrays a and b; 
int c[1000000];
#pragma omp parallel for /*重点在这里*/
for (int i = 0; i < 1000000; ++i)
  c[i] = a[i] * b[i] + a[i-1] * b[i+1];
// ... now do some processing with array c
 }

parallel for 编译指示可以帮助我们将 for 循环工作负载划分到多个线程中,每个线程都可以在不同的核心上运行,这显著减少了总的计算时间

#include <omp.h>
#include <math.h>
#include <time.h>
#include <iostream>

int main(int argc, char *argv[]) {
    int i, nthreads;
    clock_t clock_timer;
    double wall_timer;
    double c[1000000]; 
    for (nthreads = 1; nthreads <=8; ++nthreads) {
        clock_timer = clock();
        wall_timer = omp_get_wtime();
        #pragma omp parallel for private(i) num_threads(nthreads)
        for (i = 0; i < 1000000; i++) 
          c[i] = sqrt(i * 4 + i * 2 + i); 
        std::cout << "threads: " << nthreads <<  " time on clock(): " << 
            (double) (clock() - clock_timer) / CLOCKS_PER_SEC
           << " time on wall: " <<  omp_get_wtime() - wall_timer << "\n";
    }
}

上面程序可以通过不断增加线程的数量来计算运行内部 for 循环的时间。omp_get_wtime API 从一些任意的但是一致的点返回已用去的时间,以秒为单位。因此,omp_get_wtime() - wall_timer 将返回观察到的所用时间并运行 for 循环。clock() 系统调用用于预估整个程序的处理器使用时间,也就是说,将各个特定于线程的处理器使用时间相加,然后报告最终的结果。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值