机器学习和生物信息学实验室联盟

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3169|回复: 1
打印 上一主题 下一主题

openMP加速

[复制链接]
跳转到指定楼层
楼主
发表于 2014-5-5 09:44:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
类似CUDA的openACC,加一条代码就实现加速。首先要开启openmp的支持,GCC加-openmp一起编译,VS开发打开openmp支持。

openMP支持的编程语言包括C语言、C++和Fortran,支持OpenMP的编译器包括Sun Studio,Intel Compiler,Microsoft Visual Studio,GCC。我使用的是Microsoft Visual Studio 2008,CPU为Intel i5 四核,首先讲一下在Microsoft Visual Studio 2008上openMP的配置。非常简单,总共分2步:

(1) 新建一个工程。这个不再多讲。

(2) 建立工程后,点击 菜单栏->Project->Properties,弹出菜单里,点击 Configuration Properties->C/C++->Language->OpenMP Support,在下拉菜单里选择Yes。

至此配置结束。下面我们通过一个小例子来说明openMP的易用性。这个例子是 有一个简单的test()函数,然后在main()里,用一个for循环把这个test()函数跑8遍。

1 #include <iostream>
2 #include <time.h>
3 void test()
4 {
5 int a = 0;
6 for (int i=0;i<100000000;i++)
7 a++;
8 }
9 int main()
10 {
11 clock_t t1 = clock();
12 for (int i=0;i<8;i++)
13 test();
14 clock_t t2 = clock();
15 std::cout<<"time: "<<t2-t1<<std::endl;
16 }


编译运行后,打印出来的耗时为:1.971秒。下面我们用一句话把上面代码变成多核运行。

1 #include <iostream>
2 #include <time.h>
3 void test()
4 {
5 int a = 0;
6 for (int i=0;i<100000000;i++)
7 a++;
8 }
9 int main()
10 {
11 clock_t t1 = clock();
12 #pragma omp parallel for
13 for (int i=0;i<8;i++)
14 test();
15 clock_t t2 = clock();
16 std::cout<<"time: "<<t2-t1<<std::endl;
17 }


编译运行后,打印出来的耗时为:0.546秒,几乎为上面时间的1/4。


参考这个文章  http://www.eyeler.com/article-8-1.html
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享
回复

使用道具 举报

沙发
发表于 2015-12-7 15:49:58 | 只看该作者
本帖最后由 guojiasheng 于 2015-12-7 15:58 编辑

正好使用openmp,对师兄这边做个补充哈~
gcc 版本4.2以上支持openMP,实验的环境是在linux下的gcc-4.8.2编译,12核。

编译:/opt/compiler/gcc-4.8.2/bin/g++ main.c -fopenmp   (记得需要加个-fopenmp)


  1. /**
  2. * @file main.c
  3. * @author guojiasheng
  4. * @date 2015/12/04 19:27:51
  5. * @brief
  6. *  
  7. **/


  8. #include <iostream>
  9. #include <omp.h>
  10. #include <stdio.h>
  11. using namespace std;


  12. //同步标识
  13. void critical()
  14. {
  15.     int sum=0;
  16.    #pragma omp parallel
  17.     {
  18.         #pragma omp for
  19.             for (int i =0 ;i<10 ; i++)
  20.             {
  21.             #pragma omp critical
  22.                 sum += 1;
  23.             }
  24.     }
  25.     cout << "sum: " << sum << endl;
  26. }

  27. //并行
  28. void parallel()
  29. {
  30.     #pragma omp parallel

  31.     {
  32.         cout << "thread: " << omp_get_thread_num() << endl;
  33.     }
  34. }

  35. //并行for
  36. void parallelFor()
  37. {
  38. //设置并行核数
  39.     omp_set_num_threads(4);
  40. #pragma omp parallel for
  41.     for (int i=0; i<10 ;i++)
  42.         printf("thread%d,value:%d\n",omp_get_thread_num(),i);
  43. }


  44. int main(){

  45.   
  46.   critical();
  47.   parallel();
  48.   parallelFor();
  49. }


  50. /* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
复制代码



结果说明:
(1)parallel();
(2)parallelFor();
使用prarallel的话,每个线程都有执行一个printf
使用prarallel for引导的话,for会自动切分成给线程,可以看出来,线程0输出了0,1,2
(3)critical();
因为sum是共享变量,所以如果多线程不加以锁控制的话,结果会和预期的不一样,openMP内置一个标志,可以保证只有一个线程读取sum,当然这个会使得效率变低。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

机器学习和生物信息学实验室联盟  

GMT+8, 2024-5-19 12:11 , Processed in 0.066014 second(s), 18 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表