﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-C++ Coder-随笔分类-OPenMP</title><link>http://www.cppblog.com/jackdongy/category/20104.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 21 Oct 2012 05:15:04 GMT</lastBuildDate><pubDate>Sun, 21 Oct 2012 05:15:04 GMT</pubDate><ttl>60</ttl><item><title>openMP编程探索3——并行区域编程 </title><link>http://www.cppblog.com/jackdongy/archive/2012/10/21/193596.html</link><dc:creator>jackdong</dc:creator><author>jackdong</author><pubDate>Sun, 21 Oct 2012 03:55:00 GMT</pubDate><guid>http://www.cppblog.com/jackdongy/archive/2012/10/21/193596.html</guid><wfw:comment>http://www.cppblog.com/jackdongy/comments/193596.html</wfw:comment><comments>http://www.cppblog.com/jackdongy/archive/2012/10/21/193596.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jackdongy/comments/commentRss/193596.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jackdongy/services/trackbacks/193596.html</trackback:ping><description><![CDATA[<a href="http://blog.csdn.net/bendanban/article/details/6303282">http://blog.csdn.net/bendanban/article/details/6303282</a><br />
<p><span style="font-size: small">在上一节中我们讲的是一个常用的并行化编程方法（for的并行化），其实它只是并行化编程的一个特例，只是它的地位较高，或者说它比其它并行化更重要。在本节中我们将讨论一般的并行区域编程。</span></p>
<h3><a name="t0"></a><span style="font-size: small">并行区域的编译指导语句一般格式</span></h3>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; 一般格式：#pragma omp parallel [clause[clause]&#8230;]{&#8230;}</span></p>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; 其中{&#8230;}中为每个线程都执行的部分，在parallel后面可以跟随一些指导子句，例如：threadprivate、copyin等，本节中将以一些实例来依次讲解这些语句的作用。</span></p>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; 时刻记住，主线程就是0号线程，这个与for不同，另外private、firstprivate、lastprivate是for并行的东西最好不要拿来比较，尽管我在本文里比较了，但是我还是感觉有些头痛啊。</span></p>
<h3><a name="t1"></a><span style="font-size: small">例子实例</span></h3>
<p><span style="font-size: small">例1 不带指导子句的并行程序</span></p>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #pragma omp parallel指示它下面的一对大括号内的程序复制执行threads个数次。默默人情况下，所有并行区域中的变量是共享的，所以一定要谨防数据竞争的发生。 </span></p><br />
<p>&nbsp;</p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">#include&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">omp.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_62_237_Open_Text.style.display='none'; Codehighlighter1_62_237_Closed_Image.style.display='inline'; Codehighlighter1_62_237_Closed_Text.style.display='inline';" id="Codehighlighter1_62_237_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_62_237_Closed_Text.style.display='none'; Codehighlighter1_62_237_Open_Image.style.display='inline'; Codehighlighter1_62_237_Open_Text.style.display='inline';" id="Codehighlighter1_62_237_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span id="Codehighlighter1_62_237_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_62_237_Open_Text"><span style="color: #000000">{&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;#pragma&nbsp;omp&nbsp;parallel&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">2</span><span style="color: #000000">;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_128_219_Open_Text.style.display='none'; Codehighlighter1_128_219_Closed_Image.style.display='inline'; Codehighlighter1_128_219_Closed_Text.style.display='inline';" id="Codehighlighter1_128_219_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_128_219_Closed_Text.style.display='none'; Codehighlighter1_128_219_Open_Image.style.display='inline'; Codehighlighter1_128_219_Open_Text.style.display='inline';" id="Codehighlighter1_128_219_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_128_219_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_128_219_Open_Text"><span style="color: #000000">{&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">Hello&nbsp;World!&nbsp;i&nbsp;=&nbsp;%d,&nbsp;Thread&nbsp;Num&nbsp;=&nbsp;%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;i,&nbsp;omp_get_thread_num());&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
<p>&nbsp;</p>
<p><a href="http://hi.csdn.net/attachment/201104/5/0_13020046283hhN.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_13020046316uLH.gif" width="244" height="150" /></a></p>
<p align="center">图1、例1的执行结果</p>
<p align="left"><span style="font-size: small">例1的执行结果可以看出四个线程分别执行了一遍#pragma omp parallel下面的语句，想想一下如果使用#pragma omp parallel for会是什么样的结果。</span></p>
<p align="left"><span style="font-size: small">例2 使用threadprivate子句</span></p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp; 此命令表示所有并行线程使用指定变量为各自私有的，能被定义为各线程私有变量的变量只能是<strong>静态变量和全局变量</strong>。看下面的程序，希望你能发现，其实#pragma omp threadprivate()是可以单独使用的。</span></p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp; 说明一下：被定义为threadprivate的变量对于每个线程永远是活的，你在任何时候再次重新启动各线程时，前面并行时最后得到的变量值仍然保留他的值，如果你用private代替threadprivate，那么你重新启动各线程时，变量的值仍然为0。如果你不初始化要声明为private的变量，那么在串行程序中，你就不能再没有任何赋值的情况下使用它，否则会引起异常的（VS2010）。而且private不能单独像threadprivate那样定义某个变量。</span></p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp; 如果你使用另外#pragma omp threadprivate(var)，那么var必须是静态变量或者全局变量，如过你在并行开始之前并没有初始化赋值，那么每个线程中默认var的值为0.如果你赋了初值，那么每个线程中var的初值都是你赋的初始值。其中主线程就是0号线程。如果你使用了#pragma omp private(var)，那么var并不会赋初值，即使你在并行之前赋了初值。想想原先#pragma omp parallel for 的firstprivate就知道了，呵呵。在#pragma omp parallel中可以使用lastprivate，但是不能使用lastprivate，使用firstprivate(var)后，串行部分的var并不是并行时0号线程的var值，它仍未你原先赋的初值。是不是很绕啊？呵呵，你可以这样理解，使用firstprivate和private的并行都不是纯真的联合主线程的编号。这样就混不了了。</span></p>
<p>&nbsp;</p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">#include&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">omp.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;sum&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />#pragma&nbsp;omp&nbsp;threadprivate(sum)&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_108_476_Open_Text.style.display='none'; Codehighlighter1_108_476_Closed_Image.style.display='inline'; Codehighlighter1_108_476_Closed_Text.style.display='inline';" id="Codehighlighter1_108_476_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_108_476_Closed_Text.style.display='none'; Codehighlighter1_108_476_Open_Image.style.display='inline'; Codehighlighter1_108_476_Open_Text.style.display='inline';" id="Codehighlighter1_108_476_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span id="Codehighlighter1_108_476_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_108_476_Open_Text"><span style="color: #000000">{&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;#pragma&nbsp;omp&nbsp;parallel&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_141_270_Open_Text.style.display='none'; Codehighlighter1_141_270_Closed_Image.style.display='inline'; Codehighlighter1_141_270_Closed_Text.style.display='inline';" id="Codehighlighter1_141_270_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_141_270_Closed_Text.style.display='none'; Codehighlighter1_141_270_Open_Image.style.display='inline'; Codehighlighter1_141_270_Open_Text.style.display='inline';" id="Codehighlighter1_141_270_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_141_270_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_141_270_Open_Text"><span style="color: #000000">{&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="color: #000000">+=</span><span style="color: #000000">&nbsp;omp_get_thread_num();&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">parallel&nbsp;sum&nbsp;=&nbsp;%d;&nbsp;thread&nbsp;num&nbsp;=&nbsp;%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;sum,&nbsp;omp_get_thread_num());&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">/nserial&nbsp;sum&nbsp;=&nbsp;%d;&nbsp;thread&nbsp;num&nbsp;=&nbsp;%d/n/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;sum,&nbsp;omp_get_thread_num());&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;#pragma&nbsp;omp&nbsp;parallel&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">parallel&nbsp;sum&nbsp;=&nbsp;%d;&nbsp;thread&nbsp;num&nbsp;=&nbsp;%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;sum,&nbsp;omp_get_thread_num());&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
<p><br /><br />&nbsp;</p>
<p><a href="http://hi.csdn.net/attachment/201104/5/0_1302004631C7c8.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_1302004632vSQe.gif" width="244" height="198" /></a></p>
<p align="center">图2、例2执行结果</p>
<p align="left"><span style="font-size: small">threadprivate指定了sum这个变量属于每个线程，每个线程都有自己的sum变量，各个线程结束后他们的sum变量并没有注销，在此啊执行时，他们各自的sum值还保持原值。</span></p>
<p align="left"><span style="font-size: small">例3 使用copyin</span></p>
<p align="left"><span style="font-size: small">指定主线程的值拷贝到各线程中去，下面的例子中，sum是每个线程独有的，并且初始值都是0，main中第一行代码将0号线程的sum值赋为100，其它线程的sum值并没有变。</span></p>
<p>&nbsp;</p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">stdio.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">omp.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;sum;&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />#pragma&nbsp;omp&nbsp;threadprivate(sum)&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_113_509_Open_Text.style.display='none'; Codehighlighter1_113_509_Closed_Image.style.display='inline'; Codehighlighter1_113_509_Closed_Text.style.display='inline';" id="Codehighlighter1_113_509_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_113_509_Closed_Text.style.display='none'; Codehighlighter1_113_509_Open_Image.style.display='inline'; Codehighlighter1_113_509_Open_Text.style.display='inline';" id="Codehighlighter1_113_509_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span id="Codehighlighter1_113_509_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_113_509_Open_Text"><span style="color: #000000">{&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">100</span><span style="color: #000000">;&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;#pragma&nbsp;omp&nbsp;parallel&nbsp;copyin(sum)&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_174_303_Open_Text.style.display='none'; Codehighlighter1_174_303_Closed_Image.style.display='inline'; Codehighlighter1_174_303_Closed_Text.style.display='inline';" id="Codehighlighter1_174_303_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_174_303_Closed_Text.style.display='none'; Codehighlighter1_174_303_Open_Image.style.display='inline'; Codehighlighter1_174_303_Open_Text.style.display='inline';" id="Codehighlighter1_174_303_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_174_303_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_174_303_Open_Text"><span style="color: #000000">{&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="color: #000000">+=</span><span style="color: #000000">&nbsp;omp_get_thread_num();&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">parallel&nbsp;sum&nbsp;=&nbsp;%d;&nbsp;thread&nbsp;num&nbsp;=&nbsp;%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;sum,&nbsp;omp_get_thread_num());&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">/nserial&nbsp;sum&nbsp;=&nbsp;%d;&nbsp;thread&nbsp;num&nbsp;=&nbsp;%d/n/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;sum,&nbsp;omp_get_thread_num());&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;#pragma&nbsp;omp&nbsp;parallel&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">parallel&nbsp;sum&nbsp;=&nbsp;%d;&nbsp;thread&nbsp;num&nbsp;=&nbsp;%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;sum,&nbsp;omp_get_thread_num());&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
<p><br /><br />&nbsp;</p>
<p><a href="http://hi.csdn.net/attachment/201104/5/0_1302004632Qhcn.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_1302004632F9nl.gif" width="244" height="187" /></a></p>
<p align="center">图3、例3的执行结果</p>
<p align="center"><a href="http://hi.csdn.net/attachment/201104/5/0_13020046325MEC.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_1302004633a3Ja.gif" width="244" height="188" /></a></p>
<p align="center">图4、例3中将copyin(sum)删除后的执行结果</p>
<p align="left"><span style="font-size: small">通过以上图3、4可以看出copyin的用处是初始化各个线程中自己私有的sum变量。实际上定义sum为全局量时的初始值就是原sum值（如果不使用copyin的话）。<br /><br /></p>
<p>我想了想threadprivate和private以及firstprivate的区别。写出来大家讨论下。</p>
<p>1、threadprivate，限制变量为每个线程私有。被限制的变量必须具有全局特性，他的生命周期是整个程序。</p>
<p>2、private，可以限制变量为每个线程私有，但是他的生命周期是一次启动并行计算。</p>
<p>3、firstprivate，可以将穿行程序中的初值带进每个线程，变量为每个线程私有。生命周期与private相同。</p>
<p>4、还有个lastprivate的问题，他并不能在区域并行中使用。</p>
<p>大家实验把。。。</p>
<p align="left"></span></p><img src ="http://www.cppblog.com/jackdongy/aggbug/193596.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jackdongy/" target="_blank">jackdong</a> 2012-10-21 11:55 <a href="http://www.cppblog.com/jackdongy/archive/2012/10/21/193596.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>openMP编程探索2——循环并行化 </title><link>http://www.cppblog.com/jackdongy/archive/2012/10/21/193595.html</link><dc:creator>jackdong</dc:creator><author>jackdong</author><pubDate>Sun, 21 Oct 2012 03:54:00 GMT</pubDate><guid>http://www.cppblog.com/jackdongy/archive/2012/10/21/193595.html</guid><wfw:comment>http://www.cppblog.com/jackdongy/comments/193595.html</wfw:comment><comments>http://www.cppblog.com/jackdongy/archive/2012/10/21/193595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jackdongy/comments/commentRss/193595.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jackdongy/services/trackbacks/193595.html</trackback:ping><description><![CDATA[<a href="http://blog.csdn.net/bendanban/article/details/6303100">http://blog.csdn.net/bendanban/article/details/6303100</a><br /><br />&nbsp;&nbsp; openMP并不是只能对循环来并行的，循环并行化单独拿出来说是因为它在科学计算中非常有用，比如向量、矩阵的计算。所以我单独拿出这一部分给大家讲讲。这里主要讲解的是for循环。 
<h3><a name="t0"></a>编译指导语句：</h3>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; 一般格式：</span></p>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; #pragma omp parallel for [clause[clause&#8230;]]</span></p>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; for(index = first; qualification; index_expr)</span></p>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; {&#8230;}</span></p>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; 第一句中[]的部分是可选的，由自己的程序并行特点而定。大家先不要把精力放到这里面。后面的文章中会继续讲解的。</span></p>
<h3><a name="t1"></a><span style="font-size: small">并行化for的编写规则</span></h3>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; 1、index的值必须是整数，一个简单的for形式：for(int i = start; i &lt; end; i++){&#8230;} 。</span></p>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; 2、start和end可以是任意的数值表达式，但是它在并行化的执行过程中值不能改变，也就是说在for并行化执行之前，编译器必须事先知道你的程序执行多少次，因为编译器要把这些计算分配到不同的线程中执行。</span></p>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; 3、循环语句只能是单入口但出口的。这里只要你避免使用跳转语句就行了。具体说就是不能使用goto、break、return。但是可以使用continue，因为它并不会减少循环次数。另外exit语句也是可以用的，因为它的能力太大，他一来，程序就结束了。</span></p>
<h3><a name="t2"></a><span style="font-size: small">例子讲解</span></h3>
<p><span style="font-size: small">例1、for循环并行:<br /></p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><span style="color: #000000">#include&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">omp.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_62_220_Open_Text.style.display='none'; Codehighlighter1_62_220_Closed_Image.style.display='inline'; Codehighlighter1_62_220_Closed_Text.style.display='inline';" id="Codehighlighter1_62_220_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_62_220_Closed_Text.style.display='none'; Codehighlighter1_62_220_Open_Image.style.display='inline'; Codehighlighter1_62_220_Open_Text.style.display='inline';" id="Codehighlighter1_62_220_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span id="Codehighlighter1_62_220_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_62_220_Open_Text"><span style="color: #000000">{&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;#pragma&nbsp;omp&nbsp;parallel&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">12</span><span style="color: #000000">;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_141_202_Open_Text.style.display='none'; Codehighlighter1_141_202_Closed_Image.style.display='inline'; Codehighlighter1_141_202_Closed_Text.style.display='inline';" id="Codehighlighter1_141_202_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_141_202_Closed_Text.style.display='none'; Codehighlighter1_141_202_Open_Image.style.display='inline'; Codehighlighter1_141_202_Open_Text.style.display='inline';" id="Codehighlighter1_141_202_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_141_202_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_141_202_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">i&nbsp;=&nbsp;%d&nbsp;&nbsp;%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;i,&nbsp;omp_get_thread_num());&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span></div>
<p>&nbsp;</p>
<p><span style="font-size: small">例1的执行结果如图1所示：</span></p>
<p align="center"><a href="http://hi.csdn.net/attachment/201104/5/0_13019944172IZv.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_1301994418DGz8.gif" width="244" height="219" /></a></p>
<p align="center">图1、例1的执行结果</p>
<p><span style="font-size: small">从结果中可以看出 i 属于{0,1,2}时由0号线程执行，i 属于{3,4,5}时由1号线程执行，i 属于{6,7,8}时由2号线程执行，i 属于{9,10,11}时由3号线程执行。omp_get_thread_num()这个函数通过执行结果大家也知道了，他返回每个线程的编号。</span></p>
<h3><a name="t3"></a><span style="font-size: small">并行编译子句</span></h3>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; openMP中有多种并行化子句，这些子句都是为控制循环并行化编译而设定的，这里我们主要关注数据作用域子句，这里的数据作用域是指各个线程是否对某一变量有权访问。shared子句用来标记变量在各个线程之间是共享的，private子句标记变量在各个线程之间是私有的，实际上它会在在每个线程中保存一个副本。默认情况下，并行执行的变量是共享的。至于其它编译子句将在后面的文章中介绍。</span></p>
<h3><a name="t4"></a><span style="font-size: small">用实例讲解数据作用域子句</span></h3>
<p><span style="font-size: small">实际上我很难想到一个综合的例子来讲解这种子句的限制异同，所以我写了几个例子。</span></p>
<p><span style="font-size: small">例2、private</span></p>
<p>#include <br />#include "omp.h" <br />int main(int argc, char* argv[]) <br />{ <br />&nbsp;&nbsp;&nbsp; float x = 4.3f; <br />&nbsp;&nbsp;&nbsp; int i; <br />&nbsp;&nbsp;&nbsp; #pragma omp parallel for private(x) <br />&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 12; i++) <br />&nbsp;&nbsp;&nbsp; { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x = 0; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("parallel x = %.1f, thread nummber:%d/n", x, omp_get_thread_num()); <br />&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp; printf("/nserial&nbsp;&nbsp; x = %.1f, thread nummber:%d/n", x, omp_get_thread_num()); <br />&nbsp;&nbsp;&nbsp; return 0; <br />}</p>
<p><a href="http://hi.csdn.net/attachment/201104/5/0_1301994418bjX2.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_1301994418JMk4.gif" width="244" height="228" /></a></p>
<p align="center">图2、例2执行结果</p>
<p align="left"><span style="font-size: small">例3 firstprivate(var)：指定var在每个线程中都有一个副本，并且var的初始值在并行执行开始之前定义，每个并行线程的var的副本初值就是串行时定义的初始值。程序结束后串行程序中的var值并不会改变。</p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><span style="color: #000000">#include&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">omp.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_62_396_Open_Text.style.display='none'; Codehighlighter1_62_396_Closed_Image.style.display='inline'; Codehighlighter1_62_396_Closed_Text.style.display='inline';" id="Codehighlighter1_62_396_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_62_396_Closed_Text.style.display='none'; Codehighlighter1_62_396_Open_Image.style.display='inline'; Codehighlighter1_62_396_Open_Text.style.display='inline';" id="Codehighlighter1_62_396_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span id="Codehighlighter1_62_396_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_62_396_Open_Text"><span style="color: #000000">{&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">float</span><span style="color: #000000">&nbsp;x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">4.3f</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;#pragma&nbsp;omp&nbsp;parallel&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;firstprivate(x)&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">12</span><span style="color: #000000">;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_178_296_Open_Text.style.display='none'; Codehighlighter1_178_296_Closed_Image.style.display='inline'; Codehighlighter1_178_296_Closed_Text.style.display='inline';" id="Codehighlighter1_178_296_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_178_296_Closed_Text.style.display='none'; Codehighlighter1_178_296_Open_Image.style.display='inline'; Codehighlighter1_178_296_Open_Text.style.display='inline';" id="Codehighlighter1_178_296_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_178_296_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_178_296_Open_Text"><span style="color: #000000">{&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;</span><span style="color: #000000">+=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1.0f</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">parallel&nbsp;x&nbsp;=&nbsp;%.1f,&nbsp;thread&nbsp;nummber:%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;x,&nbsp;omp_get_thread_num());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">/nserial&nbsp;&nbsp;&nbsp;x&nbsp;=&nbsp;%.1f,&nbsp;thread&nbsp;nummber:%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;x,&nbsp;omp_get_thread_num());&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span></div>
<p align="left"></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p align="left"><a href="http://hi.csdn.net/attachment/201104/5/0_1301994418jHlD.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_1301994419SjZT.gif" width="244" height="231" /></a></p>
<p align="center">图3、例3的执行结果</p>
<p align="left"><span style="font-size: small">例4 lastprivate(var):指定最后多线程执行完后原串行循环最后一次var的值带到主线程（串行部分）</p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><span style="color: #000000">#include&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">omp.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_62_401_Open_Text.style.display='none'; Codehighlighter1_62_401_Closed_Image.style.display='inline'; Codehighlighter1_62_401_Closed_Text.style.display='inline';" id="Codehighlighter1_62_401_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_62_401_Closed_Text.style.display='none'; Codehighlighter1_62_401_Open_Image.style.display='inline'; Codehighlighter1_62_401_Open_Text.style.display='inline';" id="Codehighlighter1_62_401_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span id="Codehighlighter1_62_401_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_62_401_Open_Text"><span style="color: #000000">{&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">float</span><span style="color: #000000">&nbsp;x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">4.3f</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;#pragma&nbsp;omp&nbsp;parallel&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;lastprivate(x)&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">12</span><span style="color: #000000">;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_177_301_Open_Text.style.display='none'; Codehighlighter1_177_301_Closed_Image.style.display='inline'; Codehighlighter1_177_301_Closed_Text.style.display='inline';" id="Codehighlighter1_177_301_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_177_301_Closed_Text.style.display='none'; Codehighlighter1_177_301_Open_Image.style.display='inline'; Codehighlighter1_177_301_Open_Text.style.display='inline';" id="Codehighlighter1_177_301_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_177_301_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_177_301_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0.0f</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">parallel&nbsp;x&nbsp;=&nbsp;%.1f,&nbsp;thread&nbsp;nummber:%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;x,&nbsp;omp_get_thread_num());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">/nserial&nbsp;&nbsp;&nbsp;x&nbsp;=&nbsp;%.1f,&nbsp;thread&nbsp;nummber:%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;x,&nbsp;omp_get_thread_num());&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span></div>
<p align="left"></p>
<p align="center"><a href="http://hi.csdn.net/attachment/201104/5/0_1301994419wDY1.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_13019944202Cff.gif" width="244" height="227" /></a></p>
<p align="center">图4、例4的执行结果</p>
<p><span style="font-size: small">例5 firstprivate与lastprivate联用，很奇怪openMP很多情况下是不允许某个变量被指定两次规则的，他俩却可以，呵呵，而且配合效果还不错。</span></p>
<p align="left"></p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><span style="color: #000000">#include&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">omp.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_62_441_Open_Text.style.display='none'; Codehighlighter1_62_441_Closed_Image.style.display='inline'; Codehighlighter1_62_441_Closed_Text.style.display='inline';" id="Codehighlighter1_62_441_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_62_441_Closed_Text.style.display='none'; Codehighlighter1_62_441_Open_Image.style.display='inline'; Codehighlighter1_62_441_Open_Text.style.display='inline';" id="Codehighlighter1_62_441_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span id="Codehighlighter1_62_441_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_62_441_Open_Text"><span style="color: #000000">{&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">float</span><span style="color: #000000">&nbsp;x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">4.3f</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;#pragma&nbsp;omp&nbsp;parallel&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;firstprivate(x)&nbsp;lastprivate(x)&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">12</span><span style="color: #000000">;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_193_341_Open_Text.style.display='none'; Codehighlighter1_193_341_Closed_Image.style.display='inline'; Codehighlighter1_193_341_Closed_Text.style.display='inline';" id="Codehighlighter1_193_341_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_193_341_Closed_Text.style.display='none'; Codehighlighter1_193_341_Open_Image.style.display='inline'; Codehighlighter1_193_341_Open_Text.style.display='inline';" id="Codehighlighter1_193_341_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_193_341_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_193_341_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;</span><span style="color: #000000">+=</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">float</span><span style="color: #000000">)omp_get_thread_num();&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">parallel&nbsp;x&nbsp;=&nbsp;%.1f,&nbsp;thread&nbsp;nummber:%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;x,&nbsp;omp_get_thread_num());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">/nserial&nbsp;&nbsp;&nbsp;x&nbsp;=&nbsp;%.1f,&nbsp;thread&nbsp;nummber:%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;x,&nbsp;omp_get_thread_num());&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span></div>
<p align="left"></p>
<p><a href="http://hi.csdn.net/attachment/201104/5/0_1301994420RFWb.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_1301994421i670.gif" width="244" height="224" /></a></p>
<p align="center">图5、例5的执行结果</p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp; 从上面的例2、3的程序中可以看出例2中每个线程中x都是私有的，它属于每个线程，在主线程的定义并不能带入到各个线程中，使用firstprivate后，x在主线程的初始值可以带到各个线程中，在图3可以看出每个线程x的输出结果实际是相同的，但是在并行执行结束后，主线程中的x值仍然为4.3。从例4的执行结果可以看出最后x的值带出到了主线程中，这个x值到底是哪个线程中的哪？答案是最后一句x赋值后的值，哪个线程执行完的最晚就是哪个x的值。例5显示firstprivate与lastprivate联合使用的执行结果。</span></p>
<p align="left"><span style="font-size: small">例6 reduction规约操作，</span></p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp; 执行reduction的变量要特别注意，以reduction(+:sum)为例。</span></p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp; 第一种情况：sum为局部变量。这是你必须为sum在串行程序中赋初值，sum 被设置为每个线程私有，先各自执行完算出各自的sum值，最后主线程会将 《线程数+1》个sum变量规约，比如你num_thread(4),在开始并行执行之前你对规约变量赋初值为10，并行时假设每个线程算的的sum值为1，那么最终sum带到串行程序中的变量值为14（串行的10+四个线程的1）。</span></p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp; 第二种情况：sum为全局变量。这是你不必为sum赋初始值，因为此时默认串行的sum值为0，进入每个线程的sum值也是0，规约时仍然是将《线程数+1》个sum值相加，因为你并没有对全局的sum赋初值，所以最后规约的结果看着像是只有各线程的sum参加了规约操作。其实当你将全局的sum赋初值时，你会发现最后规约的sum值又多加了全局变量sum的串行程序结果。</span></p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp; 重要提醒：不管你怎样设计sum的串行声明形式，只要他在被定义为规约变量，每次进入并行线程的sum值都是0；</span></p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp; 也许你想把每个并行线程的sum值初始化成一个非0的值，然后再各自线程中在使用，那么我可以告诉你，别想了（至少我没有做到）。因为我规约sum值，如果这个规约有意义你的每个线程应该是各自独立未回各自的sum的，那么这个初始值使用0就已经非常好了，因为各自的sum计算如果结果一样，你为何不直接用一句乘法哪（线程数*一个线程计算的sum值）。</span></p>
<p align="left"></p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><span style="color: #000000">#include&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">omp.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_62_483_Open_Text.style.display='none'; Codehighlighter1_62_483_Closed_Image.style.display='inline'; Codehighlighter1_62_483_Closed_Text.style.display='inline';" id="Codehighlighter1_62_483_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_62_483_Closed_Text.style.display='none'; Codehighlighter1_62_483_Open_Image.style.display='inline'; Codehighlighter1_62_483_Open_Text.style.display='inline';" id="Codehighlighter1_62_483_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span id="Codehighlighter1_62_483_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_62_483_Open_Text"><span style="color: #000000">{&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">float</span><span style="color: #000000">&nbsp;x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0.0f</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">float</span><span style="color: #000000">&nbsp;sum&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0.0f</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />#pragma&nbsp;omp&nbsp;parallel&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">(x)&nbsp;reduction(</span><span style="color: #000000">+</span><span style="color: #000000">:sum)&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">12</span><span style="color: #000000">;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_209_379_Open_Text.style.display='none'; Codehighlighter1_209_379_Closed_Image.style.display='inline'; Codehighlighter1_209_379_Closed_Text.style.display='inline';" id="Codehighlighter1_209_379_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_209_379_Closed_Text.style.display='none'; Codehighlighter1_209_379_Open_Image.style.display='inline'; Codehighlighter1_209_379_Open_Text.style.display='inline';" id="Codehighlighter1_209_379_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_209_379_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_209_379_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">float</span><span style="color: #000000">)omp_get_thread_num();&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="color: #000000">+=</span><span style="color: #000000">&nbsp;x;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">parallel&nbsp;sum&nbsp;=&nbsp;%.1f,&nbsp;thread&nbsp;nummber:%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;sum,&nbsp;omp_get_thread_num());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">/nserial&nbsp;&nbsp;&nbsp;sum&nbsp;=&nbsp;%.1f,&nbsp;thread&nbsp;nummber:%d/n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;sum,&nbsp;omp_get_thread_num());&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span></div>
<p align="left"></p>
<p align="center"><a href="http://hi.csdn.net/attachment/201104/5/0_1301994421qwPY.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_1301994421qJ7K.gif" width="244" height="208" /></a></p>
<p align="center">图6、例6执行结果</p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp; 在例6中我使用了reduction(+:sum)，这表示每个线程对sum这个共享变量执行加操作时其它任何线程不能对它进行加操作，实际上我们这样理解是有偏差的，真正的机理在执行结果中不难看出，实际每个线程都拷贝了一个sum的副本，先在自己执行时加完sum，等所有线程都执行结束后，主线程再将每个线程的sum副本的值加起来返回给主线程中sum。</span></p>
<h3><a name="t5"></a>小结</h3>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; 本节主要讲述了for语句的并行化。现在为止大家应该可以熟练使用for并行化了。文章中可能还有些不全面的地方，热切期望各位读者能给出批评和指正，期待中&#8230;&#8230;</span></p>
<p align="left"><br /></span></p>
<p></span></p><img src ="http://www.cppblog.com/jackdongy/aggbug/193595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jackdongy/" target="_blank">jackdong</a> 2012-10-21 11:54 <a href="http://www.cppblog.com/jackdongy/archive/2012/10/21/193595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>openMP编程探索1——编程基础 </title><link>http://www.cppblog.com/jackdongy/archive/2012/10/21/193594.html</link><dc:creator>jackdong</dc:creator><author>jackdong</author><pubDate>Sun, 21 Oct 2012 03:49:00 GMT</pubDate><guid>http://www.cppblog.com/jackdongy/archive/2012/10/21/193594.html</guid><wfw:comment>http://www.cppblog.com/jackdongy/comments/193594.html</wfw:comment><comments>http://www.cppblog.com/jackdongy/archive/2012/10/21/193594.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jackdongy/comments/commentRss/193594.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jackdongy/services/trackbacks/193594.html</trackback:ping><description><![CDATA[<a href="http://blog.csdn.net/bendanban/article/details/6302857">http://blog.csdn.net/bendanban/article/details/6302857</a><br /><br />&nbsp;在学习并行编程之前，你应该知道进程、线程、主线程、从线程等基本概念。进程是一个大型应用程序的基本单位，在任务管理器里进程都有一个名称，后面跟随的是与他有关的资源。线程是程序执行的基本单位，它必须从属与一个进程，一个进程可以有多个线程，同一个进程的线程可以共享进程的资源，例如他们可以引用同一个变量的值。一个进程一般会与一个.EXE文件关联，所以我把程序和进程不加区分。一个程序中有多个线程时，它必然会有一个主线程，主线程执行完后，其它从线程也应该结束执行。 
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; 并行化编程一般可以理解为多个线程的创建和并行化编程，并行化编程的东西很多，但他们都会有两个必须的规定：1、程序执行模型。2、存储模型。</span></p>
<p><span style="font-size: small">&nbsp;&nbsp;&nbsp; 程序执行模型，他规定了并行化线程的执行方式，规则，或者说逻辑结构。openMP的执行采用了Fork-Join模型。主线程在执行过程中遇到要并行处理的部分，根据openMP的编译指导语句来创建，执行多个线程，创建的线程个数一般与计算机的核心数成正比，可以通过添加一个环境变量（OMP_NUM_THREADS）来规定创建线程的个数，注意环境变量添加后要注销或者重启系统才会生效。</span></p>
<p><a href="http://hi.csdn.net/attachment/201104/5/0_1301985327ZJtt.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_1301985327Hfs2.gif" width="304" height="192" /></a></p>
<p align="center">图1 omp程序执行模型</p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp; 存储模型，omp针对的是一个计算机或者分布式计算机的并行，在一台计算机上他采用共享存储的方式，多个线程共享一块进程的内存资源。</span></p>
<p align="left"><span style="font-size: small">&nbsp;&nbsp;&nbsp; 下面先写个程序例子，能让大家有个初步认识。这个程序是在VS2008中编译的，项目类型为Win32ConsoleApplication。</span></p>
<p align="left"><span style="font-size: small">例1、并行HelloWorld程序:</p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /><span style="color: #000000">#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">stdio.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">omp.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif"  alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])&nbsp;<br /><img onclick="this.style.display='none'; Codehighlighter1_71_271_Open_Text.style.display='none'; Codehighlighter1_71_271_Closed_Image.style.display='inline'; Codehighlighter1_71_271_Closed_Text.style.display='inline';" id="Codehighlighter1_71_271_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_71_271_Closed_Text.style.display='none'; Codehighlighter1_71_271_Open_Image.style.display='inline'; Codehighlighter1_71_271_Open_Text.style.display='inline';" id="Codehighlighter1_71_271_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span id="Codehighlighter1_71_271_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_71_271_Open_Text"><span style="color: #000000">{&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">Hello&nbsp;World!&nbsp;Serial&nbsp;Begin./n</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;#pragma&nbsp;omp&nbsp;parallel&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">开始并行执行&nbsp;</span><span style="color: #008000"><br /><img onclick="this.style.display='none'; Codehighlighter1_161_208_Open_Text.style.display='none'; Codehighlighter1_161_208_Closed_Image.style.display='inline'; Codehighlighter1_161_208_Closed_Text.style.display='inline';" id="Codehighlighter1_161_208_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_161_208_Closed_Text.style.display='none'; Codehighlighter1_161_208_Open_Image.style.display='inline'; Codehighlighter1_161_208_Open_Text.style.display='inline';" id="Codehighlighter1_161_208_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif"></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_161_208_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_161_208_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">Hello&nbsp;World!&nbsp;Parallel/n</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">Hello&nbsp;World!&nbsp;Serial&nbsp;again./n</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br /><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" />}</span></span></div>
<p align="left"></span>&nbsp;</p>
<p><span style="font-size: small">此程序编译之前，还需要你对你的编译器项目属性设置一下。这里我们以VS2008为例，首先设置项目支持openMP。右击项目-&gt;属性-&gt;C/C++-&gt;语言-&gt;openMP支持修改为是，如图2所示，然后代码生成修改为多线程调试，如图3所示。执行结果如图4所示。</span></p>
<p><a href="http://hi.csdn.net/attachment/201104/5/0_1301985328s0ii.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_13019853281ki1.gif" width="577" height="341" /></a></p>
<p align="center">图2、添加openMP支持</p>
<p align="center"><a href="http://hi.csdn.net/attachment/201104/5/0_1301985328Qkzt.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_13019853292prp.gif" width="579" height="327" /></a></p>
<p align="center">图3、多线程调试支持</p>
<p align="center"><a href="http://hi.csdn.net/attachment/201104/5/0_13019853290H58.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_1301985329kpSU.gif" width="321" height="136" /></a></p>
<p align="center">图4、执行结果</p>
<p><span style="font-size: small">以上程序我并没有设置环境变量，因为我的计算机是双核的，所以他的并行部分输出了两行Hello World！ Parallel，这说明他有两个线程执行并行部分，每个线程完全执行了相同的一段程序。我们在设置一下环境变量后在执行一下。顺便说明一下怎样设置环境变量。</span></p>
<p><span style="font-size: small">计算机右击-》属性-》高级-》环境变量-》系统变量-》新建。。。如图5所示。</span></p>
<p align="center"><a href="http://hi.csdn.net/attachment/201104/5/0_1301985330ZXaM.gif"><img title="image" style="border-left-width: 0px; border-right-width: 0px;background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://hi.csdn.net/attachment/201104/5/0_13019853309q9p.gif" width="594" height="476" /></a></p>
<p align="center">图5、Win7环境下设置环境变量</p>
<p><span style="font-size: small">设置完环境后，注销或重启系统后，再次执行例1的程序后得到的结果中<strong>Hello World！ Parallel </strong>将被执行四遍。因为你已经设置了四个线程了。</span></p>
<p><span style="font-size: small">到现在为止，大家可以模仿着例1写几个小程序了，可是还有一句话大家可能还不大明白吧，#pragma omp parallel这句话标记{}中的程序将在OMP_NUM_THREADS个线程中执行。</span></p>
<p><span style="font-size: small">在下面的几篇文章中我将继续讲解openMP编程的基础知识。欢迎继续关注。</span></p><br /><img src ="http://www.cppblog.com/jackdongy/aggbug/193594.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jackdongy/" target="_blank">jackdong</a> 2012-10-21 11:49 <a href="http://www.cppblog.com/jackdongy/archive/2012/10/21/193594.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>