- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
.NET4.0 并行计算技术基础(3)
在前面两讲中,基本上介绍完了并行计算基础理论与相关概念,学习不是目的,应用才是。因此,本讲将介绍一个并行计算的例子,并对.NET 4.0 的并行扩展作一个总体的介绍。
======================================================
19.1.3 并行计算所带来的挑战
与串行执行的程序相比,开发并行程序需要软件工程师具备一个“多线程” 的大脑。我们先来看一个引例,初步体会一下如何使用.NET 4.0 所提供的任务并行库设计并行程序。
并行计算引例
请读者仔细查看一下本节示例程序 SequentialvsParalled 的源码。此程序完成了一个非常典型的数据处理工作:递增一个整数数组的每个元素值。
示例程序将数组大小设定为 1000000,然后对数组中的每个元素进行 100 次操作,每次操作都将元素值加 1,因此,完成整个数据处理工作需要 108 次操作。
以下是串行代码:
//依次给一个数组中指定部分的元素执行OperationCounterPerDataItem 次操
作
staticvoid IncreaseNumberInSquence(int[] arr,int startIndex,int
counter)
{
}
for (int i = 0; i counter; i++)
for (int j = 0; j OperationCounterPerDataItem; j++) arr[startIndex+i]++;
上述代码在笔者的双核笔记本电脑上执行时花费了 776 毫秒。现在,使用.NET 4.0 所提供的任务并行库让上述操作并行执行:
//将任务划分为 TaskCount 个子任务,然后并行执行
static void IncreaseNumberInParallel(int[] arr)
{
int counter = DataSize / TaskCount;
Parallel.For(0, TaskCount, i =
{
counter);
}
int startIndex = i * counter; IncreaseNumberInSquence(arr, startIndex,
}
);
测试结果为 419 毫秒,并行加速系数约为 1.85。
再改算法,将对每个元素的每个操作设定为一个任务,然后再并行执行:
static void IncreaseNumberInParallel2(int[] arr)
{
为//每个数据项创建一个任务
Parallel.For(0, arr.Length, i =
{
arr[i]++);
Parallel.For(0, OperationCounterPerDataItem, j =
}
);
}
测试结果为 10057 毫秒,并行加速系数为 0.08,比串行算法慢多了!
并行计算带来的复杂性
上面所介绍的例子非常清晰地展示出并行程序设计的特殊性,并不是“并行” 总比“串行”快的,到底怎样才能获得最大的并行加速系数,需要仔细地设计并行算法,并且应该在多个典型的软硬件环境中进行对比测试,最终才能得到理想的并行设计方案。
开发并行程序的关键在于要找到一个合适的任务分解方案,并行总要付出一定的代价,比如线程同步、线程通讯、同步缓冲数据等都是开发并行程序必须认真考虑的问题。
下表对比了并行程序与串行程序的主要差别:
项目
程序行为特性
串行程序
可以预期的,相同运行环境下总可以得到相同的结果
并行程序
如果没有提供特定的同步手段,则程序执行的结果无法预期
内存访问 独占访问内存单元,数据可靠
有可能因多线程同时存取同一内存单元而引发数据存取错误
锁 不需要
死锁 不可能出现
必须为共享资源加锁
可能出现,需要仔细考虑程序中可能出现的种种情况予以避免
测试 使用代码覆盖的测试方法可以检测出绝大
多数 BUG
调试 相对简单,可以随时停止程序运行,单步
跟踪定位到每条语句和每个变量的值
由于多个线程同时并行,仅使用代码覆盖的测试方法无法检测出程序中隐藏的 BUG,并行程序的测试变得很复杂
由于多个线程同时运行,当你暂停一个线程进行调试时,其他线程可能还在运行中,因此无法保证调试环境的一致性,并行程序的调试非常困难。
正因为并行程序开发、测试和调试都比串行程序要困难,所以一般都是先编写程序的串行版本,等其工作正常之后再将其升级替换为并行版本。
何时使用“并行计算”?
根据前面的介绍,读者一定对“并行计算”有了个总体的认识,由于“并行” 需要付出代价,因此,不是所有的程序都需要转换为并行的,当要处理的数据量很大,或者要执行的数据处理任务繁重,并且这些任务本身就可
文档评论(0)