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#并行编程高级教程》
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#并行编程-并发集合 ...
随机推荐
- 【Java集合类】ArrayList详解 (JDK7)
相信对于使用过Java的人来说,ArrayList这个类大家一定不会陌生. 数据结构课上讲过, Array是数组,它能根据下标直接找到相应的地址,所以索引速度很快,但是唯一的缺点是不能动态改变数组的长 ...
- poj 2229 DP
Sumsets Time Limit: 2000MS Memory Limit: 200000K Total Submissions: 15326 Accepted: 6088 Descrip ...
- java基础:模拟ATM取款机
package com.atm; import java.util.Scanner; /** * ATM类实现 * * @author 向往的生活 */ public class ATM { publ ...
- 3359: [Usaco2004 Jan]矩形
3359: [Usaco2004 Jan]矩形 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 8 Solved: 5[Submit][Status] ...
- XML(20161113)
XML: 可扩展标记语言 在页面之间传递数据使用的,专门为了数据传输而存在 载体 HTML:超文本标记语言 显示 XML写法: 标签:<标签名></标签名> 特点:1.必须要有 ...
- 读headFirst设计模式 - 装饰者模式
继承可以在复用父类代码的情况下扩展父类的功能,但同时继承增加了对象之间的耦合度,所以要慎用继承.那么有没有既能扩展父类的功能,又能使对象间解耦的方法呢?答案是肯定的,这就是我们今天要学习的装饰者模式. ...
- 解决input的回车enter和失焦blur冲突问题:实现回车保存,blur还原编辑内容功能
最近做项目遇到: 背景:点击单元格,easyUI自动生成input可编辑框. 问题点:input的回车enter和失焦blur冲突问题:实现回车保存,blur还原编辑内容功能 要实现需求: 1.回车键 ...
- spring或springmvc自动生成applicationcontext.xml或springmvc文件(此文转载和借鉴多篇文章)
在用spring或者springmvc框架进行开发时,编辑applicationcontext.xml等配置文件是必不可少的,在eclipse中打开applicationcontext.xml通常是这 ...
- 文件IO理解
一次读取写入单个字节 public class CopyFileDemo { public static void main(String[] args) throws IOException { F ...
- JAVA基础知识(2)--关键字final的使用
/***Final关键字的使用*@author lihaiming*Email:912547587@qq.com*关键字Final可以修饰属性,方法,类*修饰属性的时候,final修饰的变量是一个常量 ...