OpenMP: OpenMP数据环境

        这是里把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; 
		// 这之前没有再次初始化fpx
		printf("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;
}

结果如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值