OpenMP: OpenMP数据环境

来源:互联网 发布:专业除甲醛公司 知乎 编辑:程序博客网 时间:2024/05/16 18:23

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

// Data Environment.cpp : 定义控制台应用程序的入口点。#include <stdio.h>#include <omp.h>int cpx = 100; // threadprivate只对全局或静态数据项有效#pragma omp threadprivate(cpx) // 必须在main外int main(int argc, char* argv[]){int i, px, fpx, lpx;px = fpx = lpx = 100;cpx = 100;printf("\n--------------------------------private--------------------------------\n");#pragma omp parallel for private(px)  // threadprivate和private的区别是private只在并行区中有效,而threadprivate属性是全局范围内有效的。for (i = 0; i < 5; i++){px = 1000;   // private构造px之后,包括主线程在内的所有变量px都是线程私有的,且需要从新初始化,否则运行出错。px += i;printf("threadnum = %d, px = %d\n",omp_get_thread_num(), px);}printf("串行 threadnum = %d, px = %d\n",omp_get_thread_num(), px); // private构造的变量是线程局部的,退出并行去后线程变量自动销毁。这里是原来的串行区对应变量px,并且和下次进入并行区的变量无关。printf("\n--------------------------------firstprivate-----------------------\n");#pragma omp parallel for firstprivate(fpx)  // 设变量属性为private,同时每个线程的这个变量的初始值为串行区对应变量的值,这样就不需要我们再次初始化。for (i = 0; i < 9; i++){fpx += i; // 这之前没有再次初始化fpxprintf("threadnum = %d, fpx = %d\n",omp_get_thread_num(), fpx);}printf("串行 threadnum = %d, fpx = %d\n",omp_get_thread_num(), fpx); //同样,因为变量属性为private,是局部的,这里的fpx还是以前的(串行区对应变量),值并没有改变。printf("\n--------------------------------lastprivate----------------------------\n");#pragma omp parallel for lastprivate(lpx)  // 最后一次迭代内的lastprivate变量的值将被带出并行区赋给串行区对应的同名变量,当然这个必须和for循环一起用,否则会出错。for (i = 0; i < 9; i++){lpx = 1000;   // lastprivate构造lpx之后,变量lpx变成线程私有的局部变量,因此需要从新初始化,否则运行出错。lpx += i;printf("threadnum = %d, lpx = %d\n",omp_get_thread_num(), lpx);}printf("串行 threadnum = %d, lpx = %d\n",omp_get_thread_num(), lpx); // lastprivate将最后一次迭代的变量值赋给了对应的全局变量,所以这里的lpx值变化了printf("--------------------------------copyin parallel first--------------------\n");cpx = 1000;#pragma omp parallel{printf("threadnum = %d, cpx = %d\n", omp_get_thread_num(), cpx); //threadprivate,主线程继承原来串行区的值,其他线程继承对应的全局变量的值。(串行区是由主线程执行的,就是说主// 线程中的cpx值之前已被更改,而其他的未变)}printf("串行 cpx=%d\n",cpx);printf("--------------------------------copyin parallel second-------------------\n");#pragma omp parallel copyin(cpx) // copyin: 把主线程(串行区)全局变量的值拷贝到各线程中同名的threadprivate变量中去。 {printf("copyin,threadnum = %d, original cpx = %d\n", omp_get_thread_num(), cpx);cpx = omp_get_thread_num();printf("after change,threadnum = %d, copyin: cpx = %d\n",omp_get_thread_num(), cpx);}printf("串行 cpx=%d\n",cpx);printf("--------------------------------copyin parallel third--------------------\n");#pragma omp parallel        //threadprivate不同于private的是前者是全局有效的,再次进入并行区,使用的还是上次退出前赋予的值printf("threadnum = %d, cpx = %d\n", omp_get_thread_num(), cpx);printf("串行 cpx=%d\n",cpx);return 0;}

结果如下:

原创粉丝点击