C#并行编程--命令式数据并行(Parallel.Invoke)---与匿名函数一起理解(转载整理)
命令式数据并行
Visual C# 2010和.NETFramework4.0提供了很多令人激动的新特性,这些特性是为应对多核处理器和多处理器的复杂性设计的。然而,因为他们包括了完整的新的特性,开发人员和架构师必须学习一种新的编程模型。
这一章是一些新的类、结构体和枚举类型,你可以使用这里来处理数据并行的场景。这章将为你展示怎样创建并行代码和描述与每个场景相关的新概念,而不是关注并发编程中的最复杂的问题。这样你将可以更加充分的理解性能改进。
开始并行任务
使用先前版本的.NET Framework,开发可以充分利用多核微处理器的并行能力的应用程序是很难的。使用那些可以控制并行的复杂结构来开始、控制、管理和同步多线程是必要的,但是这对现代的多核系统并不十分有效。
.NET 4引入了新的任务并行库(TPL),其产生在多核时代并且就是第一章中展示的轻量级并发编程模型。
为了支持数据并行、任务并行和管道,TPL提供了一个轻量级的框架,可以帮助开发人员应对不同的并行场景,实现基于任务模型的设计,而不是使用重量级复杂的线程进行工作。这些场景包括
数据并行
这里有很多的数据,并且每条数据都必须施加相同的操作。如图2-1,使用256位键的AES算法加密100个unicode字符串。

图 2-1
任务并行
这里有很多不同的操作可以并行执行,充分的利用并行的有力。例如,产生文件的哈希编码,加密unicode字符串,创建图片的缩略图。如图2-2,

图 2-2
流水线
这里混杂了任务并行和数据并行。这是最复杂的场景,因为它总是需要协调多个特定的并发任务。例如,以使用256位键的AES算法加密100个unicode字符串,然后为每个加密的字符串产生一个哈希值。这个管道可以实现同时运行两个并发执行加密和产生哈希代码两个任务。每一个加密的unicode字符串为了使用哈希编码算法进行处理而放入队列中。如图2-3,
图 2-3
当然也存在混合了前边的所有情况的复杂场景。理解怎样使用并行任务进行工作的最容易的方式就是使用他们。接下来的章节将会使用详细的例子覆盖这些最普遍的场景。
TPL引入了一个新的命名空间,System.Threading.Tasks。通过这个命名空间可以访问.NET4引入的新的类、结构体、枚举类型。所以,无论什么时候你想用TPL,使用这个命名空间是个不错的主意。
Using System.Threading.Tasks;
这样你可以避免大量的引用。例如,你可以使用Parallel.Invoke,而不是使用System.Threading.Tasks.Parallel.Invoke.
其中主要的类是Task,它代表一个异步的并发操作。然而,没有必要为了创建并行代码直接使用Task的实例。有时,最好的选择是创建并行的循环和区域。在这些场景中,你可以使用静态类Parallel提供的方法进行工作,而不是使用更底层的Task实例。
Parallel.For---为固定数目的独立For循环迭代提供负载均衡的潜在的并行执行。
Parallel.ForEach---为固定数目的独立For Each循环迭代提供负载均衡的潜在的并行执行。这种方法支持自定义分区类,这是你可以完全控制数据的分布。
Parallel.Invok---对独立的任务提供潜在的并行执行。
负载均衡的执行会尝试将工作分发在不同的任务中,这样所有的任务在大部分的时间内都可以保持繁忙。负载均衡总是试图减少任务的闲置时间。
当重构已经存在的代码来充分利用潜在的并发优势时,这些方法是很有用的。然而,理解这些并不是使用Parallel.For取代for那样简单是很重要的。
Parallel.Invoke
如果试图将很多方法并行执行最简单的方法就是使用Parallel提供的Invoke方法。以下是.NET中Parallel的Invoke函数原型。Invoke接受没有返回值(或者说返回值是void)Action[]参数数组,对操作尽可能的并行化。
public static void Invoke(params Action[] actions); /// <summary> /// 执行所提供的每个操作,而且尽可能并行运行,除非用户取消了操作。 /// </summary>
有以下四个函数:
static void First()
{
System.Console.WriteLine("1--First");
}
static void Second()
{
System.Console.WriteLine("2--Second");
}
static void Third()
{
System.Console.WriteLine("3--Third");
}
static void Fourth()
{
System.Console.WriteLine("4--Fourth");
}
使用Parallel的Invoke函数,并行执行以上四个函数。
Parallel.Invoke(
() => First(),
() => Second(),
() => Third(),
() => Fourth());
以上调用()=>First()的形式是Lambda表达式。也可以使用匿名委托来执行以上代码,如下代码所示。
Parallel.Invoke(
delegate { First(); },
delegate { Second(); },
delegate { Third(); },
delegate { Fourth(); });
或者直接传入函数参数,如下代码所示,但是使用Lambda表达式和匿名委托的一大优势:可以定义需要并行执行的多行方法,而不需要创建额外的方法。
Parallel.Invoke(
First,
Second,
Third,
Fourth);
输出结果是:
第一次执行:3-1-2-4

第二次执行:1-2-3-4

第三次执行:2-3-4-1

使用Parallel的Invoke函数时需要特别注意以下量两点:1、函数执行不要求特定的顺序。2、函数执行必须独立的,不存在特定的依赖关系。
优势和权衡
使用Parallel.Invoke的关键优势在于,这是运行并行方法的简单方式,而不用考虑任务和线程问题。然而Invoke并不适合所有情形。需要权衡一下几个方面:
如果使用Parallel.Invoke加载的方法运行时间不同,那么就需要很长的时间才能返回控制。这样很多逻辑内核就处于闲置状态。因此,使用时,一定要测量运行的结果、实现的加速比,以及逻辑内核的使用率,这是很重要的。
在并行的可扩展方面具有局限性。因为Parallel.Invoke调用的是固定数目的委托。
每次调用Parallel.Invoke都要产生一些额外开销。
与其他的并行代码一样,不同方法的任何相关性或不可控的交互会导致难以检测的bug以及意想不到的副作用。
对方法的执行顺序没有要求时,可以考虑Parallel.Invoke方法。需要特定执行顺序的复杂算法不适合使用parallel.Invoke
使用parallel.Invoke并行运行方法中,要考虑异常处理问题。
C#并行编程--命令式数据并行(Parallel.Invoke)---与匿名函数一起理解(转载整理)的更多相关文章
- C#并行编程--命令式数据并行(Parallel.Invoke)
命令式数据并行 Visual C# 2010和.NETFramework4.0提供了很多令人激动的新特性,这些特性是为应对多核处理器和多处理器的复杂性设计的.然而,因为他们包括了完整的新的特性,开 ...
- C#并行编程之数据并行
所谓的数据并行的条件是: 1.拥有大量的数据. 2.对数据的逻辑操作都是一致的. 3.数据之间没有顺序依赖. 运行并行编程可以充分的利用现在多核计算机的优势.记录代码如下: public class ...
- 并行编程多线程之Parallel
1.简介 随着多核时代的到来,并行开发越来越展示出它的强大威力!使用并行程序,充分的利用系统资源,提高程序的性能.在.net 4.0中,微软给我们提供了一个新的命名空间:System.Threadin ...
- 五 浅谈CPU 并行编程和 GPU 并行编程的区别
前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺 ...
- 第五篇:浅谈CPU 并行编程和 GPU 并行编程的区别
前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺 ...
- C#并发编程之初识并行编程
写在前面 之前微信公众号里有一位叫sara的朋友建议我写一下Parallel的相关内容,因为手中商城的重构工作量较大,一时之间无法抽出时间.近日,这套系统已有阶段性成果,所以准备写一下Parallel ...
- 一、并行编程 - 数据并行 System.Threading.Tasks.Parallel 类
一.并行概念 1.并行编程 在.NET 4中的并行编程是依赖Task Parallel Library(后面简称为TPL) 实现的.在TPL中,最基本的执行单元是task(中文可以理解为"任 ...
- 【读书笔记】.Net并行编程高级教程--Parallel
一直觉得自己对并发了解不够深入,特别是看了<代码整洁之道>觉得自己有必要好好学学并发编程,因为性能也是衡量代码整洁的一大标准.而且在<失控>这本书中也多次提到并发,不管是计算机 ...
- C#并行编程-Parallel
菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...
随机推荐
- Heap(堆)和stack(栈)有的区别是什么。
java的内存分为两类,一类是栈内存,一类是堆内存.栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个 ...
- visual studio的项目属性表
最近发现一个有趣的东西:visual studio的项目属性表 我下载了cocos2d-x-3.0alpha1,然后发现HelloLua项目配置里没有配include搜索目录和依赖库以及一个Marco ...
- codeforces 474D.Flowers 解题报告
题目链接:http://codeforces.com/problemset/problem/474/D 题目意思:Marmot 吃两种类型的花(实在难以置信呀--):red 或者 white,如果要吃 ...
- Ubuntu下装QQ2014
1.首先我们需要下载一个 deb的 Wine QQ安装包 qq2014官方下载:http://www.longene.org/download/WineQQ2013SP6-20140102-Longe ...
- hdu 4832 dp ***
dp1[i][j]表示只走x轴走j步到i位置有多少总走法,dp2同,dp方程就很好写 wa了无数发,发现MOD写在INF上了 #include<cstdio> #include<io ...
- 以app形式启动chrome——关于chrome命令行
转自:http://wiselyman.iteye.com/blog/2179043 转自:http://bbs.ithome.com/thread-589651-1-1.html 转自:http:/ ...
- Android开发之日历控件实现
Android开发之日历控件实现:以下都是转载的. 日历控件 日历控件 日历控件 日历控件
- 网站构建学习笔记(0)——基本概念了解及资源学习(copy自w3school)
一.学习方面 1.WWW - 万维网 什么是 WWW? WWW 指万维网(World Wide Web) 万维网常被称为Web Web 是由遍布全球的计算机所组成的网络 所有 Web 中的计算机都可以 ...
- sql2005-数据库备份方案 (转载)
sql2005数据库备份一般情况分为二种:一是手工备份.二是自动备份.以下是二种方法的步骤: 一.手工备份 打开数据库,选择要备份数据库,右键选择[任务]->[备份],打开备份数据库页面,在[源 ...
- SQL事务用法begin tran,commit tran和rollback tran的用法
Sql Server 2005/2008中提供了begin tran,commit tran和rollback tran来使用事务. begin tran表示开始事务, commit tran表示提交 ...