OpenMP模式下多线程文件操作

本文介绍了使用OpenMP进行多线程编程的基础知识,特别是在Windows环境下,利用Visual Studio 2010进行开发。文章讨论了多线程文件操作可能遇到的线程冲突问题,并详细讲解了OpenMP的头文件、预处理指令以及常用库函数。通过实例代码展示了如何并行化for循环,强调了数据不相关性和并行化的约束条件。最后,提到了嵌套for循环的并行处理方式。

项目背景:

      为了提升项目的运行效率,考虑多线程技术。最近OpenMP技术很热,咱也凑凑热闹,也为了充分发挥电脑硬件的能力。

 

硬件:

      酷睿2双核 2.2GHz

      3G 内存

 

软件:

      Visual Studio 2010 旗舰版

      Windows 7 旗舰版 32bit

 

难点:

      由于多个线程操作同一个文件,很有可能存在线程冲突。

 

OpenMP:

      1. 必须的头文件 <omp.h>

 

      2. #pragma omp 预处理指示符指定要采用OpenMP。 例如通过 #pragma om parallel for 来指定下方的for循环采用多线程执行,此时编译器会根据CPU的个数来创建线程数。对于双核系统,编译器会默认创建两个线程执行并行区域的代码。

      示例代码:

     

 

      3. OpenMP 常用库函数

      函数原型                                         功能

      int omp_get_num_procs(void)      返回当前可用的处理器个数

      int omp_get_num_threads(void)  返回当前并行区域中活动线程的个数,如果在并行区域外部调用,返回1

      int omp_get_thread_num(void)    返回当前的线程号(omp_get_thread_ID更好一些)

      int omp_set_num_threads(void)   设置进入并行区域时,将要创建的线程个数

      3.1 并行区域

     

      3.2 库函数示例

     

     

      3.3 for循环并行化的基本用法

      3.3.1 数据不相关性

      利用openmp实现for循环的并行化,需满足数据的不相关性。

      在循环并行化时,多个线程同时执行循环,迭代的顺序是不确定的。如果数据是非相关的,那么可以采用基本的 #pragma omp parallel for 预处理指示符。

      如果语句S2与语句S1相关,那么必然存在以下两种情况之一:

      1. 语句S1在一次迭代中访问存储单元L,而S2在随后的一次迭代中访问同一存储单元,称之为循环迭代相关(loop carried dependence);

      2. S1和S2在同一循环迭代中访问同一存储单元L,但S1的执行在S2之前,称之为非循环迭代相关(loop-independent dependence)。

    

       3.3.2 for循环并行化的几种声明形式

      

 

       上面代码的两种声明形式是一样的,可见第二种形式更为简洁。不过,第一种形式有一个好处:可以在并行区域内、for循环以外插入其他并行代码。

      

 

       3.3.3 for 循环并行化的约束条件

       尽管OpenMP可以很方便地对for循环进行并行化,但并不是所有的for循环都可以并行化。下面几种情形的for循环便不可以:

       1. for循环的循环变量必须是有符号型。例如,for(unsigned int i = 0; i < 10; ++i){...}编译不通过。

       2. for循环的比较操作符必须是<, <=, >, >=。例如,for(int i = 0; i != 10; i++)编译不通过。

       3. for循环的增量必须是整数的加减,而且必须是一个循环不变量。例如,for(int i = 0; i < 10; i = i+1)编译不通过,感觉只能++i, i++, --i, i--。

       4. for循环的比较操作符如果是<, <=,那么循环变量只能增加。例如,for(int i = 0; i != 10; --i)编译不通过。

       5. 循环必须是单入口,单出口。循环内部不允许能够达到循环以外的跳出语句,exit除外。异常的处理也不必须在循环体内部处理。例如,如循环体内的break或者goto语句,会导致编译不通过。

 

       3.3.4 基本for循环并行化示例

      

 

       3.3.5 嵌套for循环

      

       编译器会让第一个CPU完成

      

       让第二个CPU完成

      

 

未完待续......

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值