OpenMP学习之--数据环境(代码示例)

来源:互联网 发布:寻求淘宝合作伙伴 编辑:程序博客网 时间:2024/04/30 01:21

原文地址:http://blog.csdn.net/augusdi/article/details/8807541


这是里把OpenMP常用的数据环境construct用代码示例的方法写出来了,主要包括private,firstprivate,lastprivate和copyin。注释部分对这几种construct作用和区别描述已经很详细了,这里就补多说,相信演示代码会有更好的效果。

[cpp] view plaincopyprint?
  1. // Data Environment.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "omp.h"
  5. int cpx = 100;
  6. // threadprivate只对全局或静态数据项有效
  7. #pragma omp threadprivate(cpx)
  8. // 必须在main外
  9. int _tmain(int argc, _TCHAR* argv[])
  10. {
  11. int i, px, fpx, lpx;
  12. px=fpx=lpx= 100;
  13. cpx = 100;
  14. printf("/n--------------------------------private--------------------------------/n");
  15. #pragma omp parallel for private(px)
  16. // threadprivate和private的区别是private只在并行区中有效,而threadprivate属性是全局范围内有效的。
  17. for (i=0; i<5; i++)
  18. {
  19. px = 1000;
  20. // private构造px之后,包括主线程在内的所有变量px都是线程私有的,且需要从新初始化,否则运行出错。
  21. px += i;
  22. printf("threadnum = %d, px = %d/n",omp_get_thread_num(), px);
  23. }
  24. printf("串行 threadnum = %d, px = %d/n",omp_get_thread_num(), px);
  25. // private构造的变量是线程局部的,退出并行去后线程变量自动销毁。这里是原来的串行区对应变量px,并且和下次进入并行区的
  26. 变量无关。
  27. printf("/n--------------------------------firstprivate--------------------------------/n");
  28. #pragma omp parallel for firstprivate(fpx)
  29. // 设变量属性为private,同时每个线程的这个变量的初始值为串行区对应变量的值,这样就不需要我们再次初始化。
  30. for (i=0; i<9; i++)
  31. {
  32. fpx += i;
  33. // 这之前没有再次初始化fpx
  34. printf("threadnum = %d, fpx = %d/n",omp_get_thread_num(), fpx);
  35. }
  36. printf("串行 threadnum = %d, fpx = %d/n",omp_get_thread_num(), fpx);
  37. //同样,因为变量属性为private,是局部的,这里的fpx还是以前的(串行区对应变量),值并没有改变。
  38. printf("/n--------------------------------lastprivate--------------------------------/n");
  39. #pragma omp parallel for lastprivate(lpx)
  40. // 最后一次迭代内的lastprivate变量的值将被带出并行区赋给串行区对应的同名变量,当然这个必须和for循环一起用,否则会出错。
  41. for (i=0; i<9; i++)
  42. {
  43. lpx = 1000;
  44. // lastprivate构造lpx之后,变量lpx变成线程私有的局部变量,因此需要从新初始化,否则运行出错。
  45. lpx += i;
  46. printf("threadnum = %d, lpx = %d/n",omp_get_thread_num(), lpx);
  47. }
  48. printf("串行 threadnum = %d, lpx = %d/n",omp_get_thread_num(), lpx);
  49. // lastprivate将最后一次迭代的变量值赋给了对应的全局变量,所以这里的lpx值变化了
  50. printf("--------------------------------copyin parallel first--------------------------------/n");
  51. cpx = 1000;
  52. #pragma omp parallel
  53. {
  54. printf("threadnum = %d, cpx = %d/n", omp_get_thread_num(), cpx);
  55. //threadprivate,主线程继承原来串行区的值,其他线程继承对应的全局变量的值。(串行区是由主线程执行的,就是说主
  56. 线程中的cpx值之前已被更改,而其他的未变)
  57. }
  58. printf("串行 cpx=%d/n",cpx);
  59. printf("--------------------------------copyin parallel second--------------------------------/n");
  60. #pragma omp parallel copyin(cpx)
  61. // copyin: 把主线程(串行区)全局变量的值拷贝到各线程中同名的threadprivate变量中去。
  62. {
  63. printf("copyin,threadnum = %d, original cpx = %d/n", omp_get_thread_num(), cpx);
  64. cpx = omp_get_thread_num();
  65. printf("after change,threadnum = %d, copyin: cpx = %d/n",omp_get_thread_num(), cpx);
  66. }
  67. printf("串行 cpx=%d/n",cpx);
  68. printf("--------------------------------copyin parallel third--------------------------------/n");
  69. #pragma omp parallel
  70. //threadprivate不同于private的是前者是全局有效的,再次进入并行区,使用的还是上次退出前赋予的值
  71. printf("threadnum = %d, cpx = %d/n", omp_get_thread_num(), cpx);
  72. printf("串行 cpx=%d/n",cpx);
  73. return 0;
  74. }

下面是程序的输出结果:

[c-sharp] view plaincopyprint?
  1. --------------------------------private--------------------------------
  2. threadnum = 0, px = 1000
  3. threadnum = 2, px = 1003
  4. threadnum = 0, px = 1001
  5. threadnum = 3, px = 1004
  6. threadnum = 1, px = 1002
  7. 串行 threadnum = 0, px = 100
  8. --------------------------------firstprivate--------------------------------
  9. threadnum = 0, fpx = 100
  10. threadnum = 0, fpx = 101
  11. threadnum = 2, fpx = 105
  12. threadnum = 0, fpx = 103
  13. threadnum = 2, fpx = 111
  14. threadnum = 3, fpx = 107
  15. threadnum = 3, fpx = 115
  16. threadnum = 1, fpx = 103
  17. threadnum = 1, fpx = 107
  18. 串行 threadnum = 0, fpx = 100
  19. --------------------------------lastprivate--------------------------------
  20. threadnum = 0, lpx = 1000
  21. threadnum = 1, lpx = 1003
  22. threadnum = 0, lpx = 1001
  23. threadnum = 1, lpx = 1004
  24. threadnum = 0, lpx = 1002
  25. threadnum = 3, lpx = 1007
  26. threadnum = 3, lpx = 1008
  27. threadnum = 2, lpx = 1005
  28. threadnum = 2, lpx = 1006
  29. 串行 threadnum = 0, lpx = 1008
  30. --------------------------------copyin parallel first--------------------------------
  31. threadnum = 0, cpx = 1000
  32. threadnum = 1, cpx = 100
  33. threadnum = 3, cpx = 100
  34. threadnum = 2, cpx = 100
  35. 串行 cpx=1000
  36. --------------------------------copyin parallel second--------------------------------
  37. copyin,threadnum = 1, original cpx = 1000
  38. after change,threadnum = 1, copyin: cpx = 1
  39. copyin,threadnum = 3, original cpx = 1000
  40. after change,threadnum = 3, copyin: cpx = 3
  41. copyin,threadnum = 2, original cpx = 1000
  42. copyin,threadnum = 0, original cpx = 1000
  43. after change,threadnum = 2, copyin: cpx = 2
  44. after change,threadnum = 0, copyin: cpx = 0
  45. 串行 cpx=0
  46. --------------------------------copyin parallel third--------------------------------
  47. threadnum = 0, cpx = 0
  48. threadnum = 1, cpx = 1
  49. threadnum = 3, cpx = 3
  50. threadnum = 2, cpx = 2
  51. 串行 cpx=0  

原创粉丝点击