- 浏览: 2162547 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1878)
- [网站分类]ASP.NET (141)
- [网站分类]C# (80)
- [随笔分类]NET知识库 (80)
- [随笔分类]摘抄文字[非技术] (3)
- [随笔分类]养生保健 (4)
- [网站分类]读书区 (16)
- [随笔分类]赚钱 (7)
- [网站分类].NET新手区 (233)
- [随笔分类]网站 (75)
- [网站分类]企业信息化其他 (4)
- [网站分类]首页候选区 (34)
- [网站分类]转载区 (12)
- [网站分类]SQL Server (16)
- [网站分类]程序人生 (7)
- [网站分类]WinForm (2)
- [随笔分类]错误集 (12)
- [网站分类]JavaScript (3)
- [随笔分类]小说九鼎记 (69)
- [随笔分类]技术文章 (15)
- [网站分类]求职面试 (3)
- [网站分类]其他技术区 (6)
- [网站分类]非技术区 (10)
- [发布至博客园首页] (5)
- [网站分类]jQuery (6)
- [网站分类].NET精华区 (6)
- [网站分类]Html/Css (10)
- [随笔分类]加速及SEO (10)
- [网站分类]Google开发 (4)
- [随笔分类]旅游备注 (2)
- [网站分类]架构设计 (3)
- [网站分类]Linux (23)
- [随笔分类]重要注册 (3)
- [随笔分类]Linux+PHP (10)
- [网站分类]PHP (11)
- [网站分类]VS2010 (2)
- [网站分类]CLR (1)
- [网站分类]C++ (1)
- [网站分类]ASP.NET MVC (2)
- [网站分类]项目与团队管理 (1)
- [随笔分类]个人总结 (1)
- [随笔分类]问题集 (3)
- [网站分类]代码与软件发布 (1)
- [网站分类]Android开发 (1)
- [网站分类]MySQL (1)
- [网站分类]开源研究 (6)
- ddd (0)
- 好久没写blog了 (0)
- sqlserver (2)
最新评论
-
JamesLiuX:
博主,能组个队么,我是Freelancer新手。
Freelancer.com(原GAF – GetAFreelancer)帐户里的钱如何取出? -
yw10260609:
我认为在混淆前,最好把相关代码备份一下比较好,不然项目完成后, ...
DotFuscator 小记 -
日月葬花魂:
大哥 能 加我个QQ 交流一下嘛 ?51264722 我Q ...
web应用程序和Web网站区别 -
iaimg:
我想问下嵌入delphi写的程序总是出现窗体后面感觉有个主窗体 ...
C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部 -
iaimg:
代码地址下不了啊!
C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部
引言
随着CPU多核的普及,编程时充分利用这个特性越显重要。上篇首先用传统的嵌套循环进行数组填充,然后用.NET 4.0中的System.Threading.Tasks提供的Parallel Class来并行地进行填充,最后对比他们的性能。本文将深入分析Parallel Class并借机回答上篇9楼提出的问题,而System.Threading.Tasks分析,这个将推迟到.NET(C#) Internals: 以一个数组填充的例子初步了解.NET 4.0中的并行(三)中介绍。内容如下:
- 1、Parallel Class
- 1.1、For方法
- 1.2、ForEach方法
- 1.3、Invoke方法
- 2、并发控制疑问?
- 2.1、使用Lock锁
- 2.2、使用PLINQ——用AsParallel
- 2.3、使用PLINQ——用ParallelEnumerable
- 2.4、使用Interlocked操作
- 2.5、使用Parallel.For的有Thread-Local变量重载函数
- 性能比较
1、Parallel Class
Parallel——这个类提供对通常操作(诸如for、foreach、执行语句块)基于库的数据并行替换。它只是System.Threading.Tasks命名空间的一个类,该命名空间中还包括很多其他的类。下面举个例子来说明如何使用Parallel.For(来自MSDN):
01 |
using System.Threading.Tasks;
|
02 |
class Test
|
03 |
{ |
04 |
static int N = 1000;
|
05 |
|
06 |
static void TestMethod()
|
07 |
{
|
08 |
// Using a named method.
|
09 |
Parallel.For(0, N, Method2);
|
10 |
|
11 |
// Using an anonymous method.
|
12 |
Parallel.For(0, N, delegate ( int i)
|
13 |
{
|
14 |
// Do Work.
|
15 |
});
|
16 |
|
17 |
// Using a lambda expression.
|
18 |
Parallel.For(0, N, i =>
|
19 |
{
|
20 |
// Do Work.
|
21 |
});
|
22 |
}
|
23 |
|
24 |
static void Method2( int i)
|
25 |
{
|
26 |
// Do work.
|
27 |
}
|
28 |
} |
上面这个例子简单易懂,上篇我们就是用的Parallel.For,这里就不解释了。其实Parallel类的方法主要分为下面三类:
- For方法
- ForEach方法
- Invoke方法
1.1、For方法
在里面执行的for循环可能并行地运行,它有12个重载。这12个重载中Int32参数和Int64参数的方法各为6个,下面以Int32为例列出:
- For(Int32 fromInclusive, Int32 toExclusive, Action<Int32> body),该方法对区间(fromInclusive,toExclusive)之间的迭代调用body表示的委托。body委托有一个迭代数次的int32参数,如果fromInclusive>=toExclusive,则不会执行任何迭代。
-
For(Int32 fromInclusive, Int32 toExclusive, Action<Int32, ParallelLoopState>),该方法对区间(fromInclusive, toExclusive)之间的迭代调用body表示的委托。body委托有两个参数——表示迭代数次的int32参数、一个可用于过早地跳出循环的ParallelLoopState实例。如果fromInclusive>=toExclusive,则不会执行任何迭代。
调用Break通知For操作当前迭代之后的迭代不需要执行。然而,在此之前的迭代如果没有完成仍然需要执行。因此,调用Break类似于调用break跳出传统的for循环,不是break的原因是它不保证当前迭代之后的迭代绝对不会执行。
如果在当前迭代之前的迭代不必要执行,应该调用Stop而不是Break。调用Stop通知For循环放弃剩下的迭代,不管它是否在当前迭代之前或之后,因为所以要求的工作已经完成。然而,Break并不能保证这个。 - For(Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action<Int32> body),跟第一个方法类似,但它的区间是[fromInclusive, toExclusive)。
- For(Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action<Int32, ParallelLoopState> body),跟第二个方法类似,单的区间是[fromInclusive, toExclusive)。
- For<TLocal>(Int32 fromInclusive, Int32 toExclusive, Func<TLocal> localInit, Func<Int32, ParallelLoopState, TLocal, TLocal> body, Action<TLocal> localFinally),它的迭代区间是[fromInclusive, toExclusive)。另外body有两个local状态变量用于同一线程的迭代之间共享。localInit委托将在每个线程参与循环执行时调用,并返回这些线程初始的local状态。这些初始状态被传递给body,当它在每个线程上第一次调用时。然后,接下来body调用返回一个可能的修改状态值且传递给下一次body调用。最终,最后一次在每个线程上的body调用返回的一个状态值传递给localFinally委托。每个线程执行在自己的loacl 状态上执行最后一个动作时,localFinally委托将被调用。这个委托可能在多个线程上并发执行,因此,你必须同步访问任何共享变量。
- For<TLocal>(Int32, Int32, ParallelOptions, Func<TLocal>, Func<Int32, ParallelLoopState, TLocal, TLocal>, Action<TLocal>),跟上面的方法类似。
下面代码演示了For(Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action<Int32> body)方法(来自MSDN):
01 |
using System;
|
02 |
using System.Collections.Generic;
|
03 |
using System.Linq;
|
04 |
using System.Text;
|
05 |
using System.Threading;
|
06 |
using System.Threading.Tasks;
|
07 |
|
08 |
namespace ConsoleApplication2
|
09 |
{ |
10 |
class Program
|
11 |
{
|
12 |
// Demonstrated features:
|
13 |
// CancellationTokenSource
|
14 |
// Parallel.For()
|
15 |
// ParallelOptions
|
16 |
// ParallelLoopResult
|
17 |
// Expected results:
|
18 |
// An iteration for each argument value (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) is executed.
|
19 |
// The order of execution of the iterations is undefined.
|
20 |
// The iteration when i=2 cancels the loop.
|
21 |
// Some iterations may bail out or not start at all; because they are temporally executed in unpredictable order,
|
22 |
// it is impossible to say which will start/complete and which won't.
|
23 |
// At the end, an OperationCancelledException is surfaced.
|
24 |
// Documentation:
|
26 |
|
27 |
static void Main( string [] args)
|
28 |
{
|
29 |
CancellationTokenSource cancellationSource = new CancellationTokenSource();
|
30 |
ParallelOptions options = new ParallelOptions();
|
31 |
options.CancellationToken = cancellationSource.Token;
|
32 |
try
|
33 |
{
|
34 |
ParallelLoopResult loopResult = Parallel.For(
|
35 |
0,
|
36 |
10,
|
37 |
options,
|
38 |
(i, loopState) =>
|
39 |
{
|
40 |
Console.WriteLine( "Start Thread={0}, i={1}" , Thread.CurrentThread.ManagedThreadId, i);
|
41 |
|
42 |
// Simulate a cancellation of the loop when i=2
|
43 |
if (i == 2)
|
44 |
{
|
45 |
cancellationSource.Cancel();
|
46 |
}
|
47 |
|
48 |
// Simulates a long execution
|
49 |
for ( int j = 0; j < 10; j++)
|
50 |
{
|
51 |
Thread.Sleep(1 * 200);
|
52 |
|
53 |
// check to see whether or not to continue
|
54 |
if (loopState.ShouldExitCurrentIteration) return ;
|
55 |
}
|
56 |
|
57 |
Console.WriteLine( "Finish Thread={0}, i={1}" , Thread.CurrentThread.ManagedThreadId, i);
|
58 |
}
|
59 |
);
|
60 |
if (loopResult.IsCompleted)
|
61 |
{
|
62 |
Console.WriteLine( "All iterations completed successfully. THIS WAS NOT EXPECTED." );
|
63 |
}
|
64 |
}
|
65 |
// No exception is expected in this example, but if one is still thrown from a task,
|
66 |
// it will be wrapped in AggregateException and propagated to the main thread.
|
67 |
catch (AggregateException e)
|
68 |
{
|
69 |
Console.WriteLine( "Parallel.For has thrown an AggregateException. THIS WAS NOT EXPECTED.\n{0}" , e);
|
70 |
}
|
71 |
// Catching the cancellation exception
|
72 |
catch (OperationCanceledException e)
|
73 |
{
|
74 |
Console.WriteLine( "An iteration has triggered a cancellation. THIS WAS EXPECTED.\n{0}" , e.ToString());
|
75 |
}
|
76 |
}
|
77 |
}
|
78 |
} |
1.2、ForEach方法
在迭代中执行的foreach操作可能并行地执行,它有20个重载。这个方法太多,但用法大概跟For方法差不多,请自行参考MSDN。
1.3、Invoke方法
提供的每个动作可能并行地执行,它有2个重载。
- Invoke(params Action[] actions):actions是一个要执行的动作数组,这些动作可能并行地执行,但并不保证执行的顺序及一定并行执行。这个方法直到提供的所有操作完成时才返回,不管是否正常地完成或异常终止。
- Invoke(ParallelOptions parallelOptions, params Action[] actions):跟上面的方法类似,只是增加了一个parallelOptions参数,可以用户调用者取消整个操作。
例如下面代码执行了三个操作(来自MSDN):
01 |
using System;
|
02 |
using System.Collections.Generic;
|
03 |
using System.Linq;
|
04 |
using System.Text;
|
05 |
using System.Threading;
|
06 |
using System.Threading.Tasks;
|
07 |
|
08 |
namespace ConsoleApplication2
|
09 |
{ |
10 |
class Program
|
11 |
{
|
12 |
static void Main()
|
13 |
{
|
14 |
try
|
15 |
{
|
16 |
Parallel.Invoke(
|
17 |
BasicAction, // Param #0 - static method
|
18 |
() => // Param #1 - lambda expression
|
19 |
{
|
20 |
Console.WriteLine( "Method=beta, Thread={0}" , Thread.CurrentThread.ManagedThreadId);
|
21 |
},
|
22 |
delegate () // Param #2 - in-line delegate
|
23 |
{
|
24 |
Console.WriteLine( "Method=gamma, Thread={0}" , Thread.CurrentThread.ManagedThreadId);
|
25 |
}
|
26 |
);
|
27 |
}
|
28 |
// No exception is expected in this example, but if one is still thrown from a task,
|
29 |
// it will be wrapped in AggregateException and propagated to the main thread.
|
30 |
catch (AggregateException e)
|
31 |
{
|
32 |
Console.WriteLine( "An action has thrown an exception. THIS WAS UNEXPECTED.\n{0}" , e.InnerException.ToString());
|
33 |
}
|
34 |
}
|
35 |
|
36 |
static void BasicAction()
|
37 |
{
|
38 |
Console.WriteLine( "Method=alpha, Thread={0}" , Thread.CurrentThread.ManagedThreadId);
|
39 |
}
|
40 |
}
|
41 |
} |
2、并发控制疑问?
有人提出以下疑问:“如果For里面的东西,对于顺序敏感的话,会不会有问题。并行处理的话,说到底应该是多线程。如果需要Lock住什么东西的话,应该怎么做呢?例如这个例子不是对数组填充,是对文件操作呢?对某个资源操作呢?”
关于对顺序敏感的话,也就是说该如何加锁来控制?下面我举个例子来说明:对1~1000求和。如果我们想上篇那样简单地用Parallel.For,将会产生错误的结果,代码如下:
01 |
using System;
|
02 |
using System.Collections.Generic;
|
03 |
using System.Linq;
|
04 |
using System.Text;
|
05 |
using System.Threading;
|
06 |
using System.Threading.Tasks;
|
07 |
|
08 |
namespace ConsoleApplication2
|
09 |
{ |
10 |
class Program
|
11 |
{
|
12 |
static void Main( string [] args)
|
13 |
{
|
14 |
int loops=0;
|
15 |
while (loops <= 100)
|
16 |
{
|
17 |
long sum = 0;
|
18 |
Parallel.For(1, 1001, delegate ( long i)
|
19 |
{
|
20 |
sum += i;
|
21 |
});
|
22 |
System.Console.WriteLine(sum);
|
23 |
loops++;
|
24 |
}
|
25 |
}
|
26 |
}
|
27 |
} |
在上述代码中,为了校验正确性我进行了重复做了100次,得出如下结果:
-
你应该知道的10个奇特的 HTML5 单页网站
2013-10-25 21:46 807网页设计师努力寻找新的方式来展现内容。其中一个大的趋势是单页 ... -
用tsmmc.MSC方式在xp和Win7集中管理多台Win2003服务器
2010-12-18 14:08 1338远程桌面管理:tsmmc.msc在xp系统中的使用wind ... -
.Net 4.0并行库实用性演练[1]
2010-12-23 21:21 1198自VS2010发布近半年了,虽然整天想学习新东西,要更新到自己 ... -
.net 代码混淆原理性实践
2010-11-21 21:53 1669现在我们已经很清楚,托管PE文件可以轻而易举的被反编译,如果您 ... -
ASP.NET中的两个Cookie类:HttpCookie类与Cookie类
2010-07-29 09:43 1916System.Web.HttpCookie类, ... -
SQL的老题目:查询学生平均成绩及其名次
2010-06-18 23:24 4274Student(S#,Sname,Sage,Ssex) 学生表 ... -
去除狂人采集器添加在帖子中的广告信息
2010-06-18 16:28 2200去除狂人采集器添加在帖子中的广告信息 我的网站要转型 ... -
petshop4.0 详解之四(PetShop之ASP.NET缓存)
2010-04-03 09:01 1385如果对微型计算机硬件系统有足够的了解,那么我们对于Cache这 ... -
.NET 开发系统 -知识 点
2010-04-01 09:12 1298安全 性能 调试 Security ... -
织梦部分采集规则-DedeCms
2010-04-01 09:13 9241.幻剑书盟小说采集节点 {dede:comments} ... -
网站静态化结构
2009-12-16 09:21 801写在前头 静态化是解决减轻网站压力,提高网站访问速度的常用方 ... -
Memcache安装
2009-12-16 09:26 809Memcache安装 服务器端下载地址:http:// ... -
memcache_engine + memcachedb = 高性能分布式内存数据库
2009-12-16 09:35 1093memcachedb是一个由新浪网的开发人员开放出来的开源项目 ... -
一个简单的jQuery插件ajaxfileupload实现ajax上传文件例子
2009-12-16 13:10 1552页面代码: <html> <!-- ... -
jQuery Ajax 方法调用 Asp.Net WebService 的详细例子
2009-12-16 13:26 875这很常用,搜索了一下博客园的“找找看”和谷歌,看到大部分都是 ... -
event.keyCode列表
2009-12-16 15:31 1311Keycode对照表 字母和数字键的键码值(keyCo ... -
sql 求差值
2009-12-17 13:15 1167有一组数据,这组数据是不断增加的,想求每小时的差值,规则是:本 ... -
限制文本框只能输入两位数字_我 里面有吗?
2009-12-18 13:44 1126function isTriDecimal(value){ ... -
Resharper进阶一
2009-12-18 15:12 1126Resharper进阶一:简要介绍 面对这样一个问题:为什 ... -
文本框 价格 保留两位小数 讨论
2009-12-21 21:35 1092不知道大家是怎么实现的? 1,用js控制的话,在firefox ...
相关推荐
PLINQ是.NET 4.0中的并行查询库,它扩展了LINQ(Language Integrated Query)以支持并行查询。PLINQ自动识别数据源是否支持并行处理,并在可能的情况下,使用多线程加速查询。开发者可以通过简单地添加一个....
8. **并发和并行计算**:.NET Framework 4.0引入了Task Parallel Library(任务并行库),使得开发者可以更容易地利用多核处理器进行并发编程。此外,还有Parallel LINQ(PLINQ)提供并行查询的支持。 9. **垃圾...
本技术资源包括了我在博客上发表的“.NET 4.0并行计算技术基础”系列文章中的所有示例源码,并包含一个PDF,汇总了所有文章。 与作者互动请访问http://blog.csdn.net/bitfan/archive/2009/10/26/4728180.aspx 更多...
### comsol 4.0 cluster 并行计算培训课程知识点详解 #### 一、课程概述 本培训课程主要针对COMSOL Multiphysics 4.0版本中的集群并行计算功能进行详细介绍。通过该课程的学习,学员将能够掌握如何利用Windows HPC ...
2. **可空类型(Nullable Types)**:C# 4.0中对所有值类型都支持可空性,这在处理可能为null的变量时非常实用。例如,`int?`表示一个可以为null的整数。 3. **泛型协变和逆变(Generic Covariance and ...
总的来说,这个压缩包包含了从.NET 3.5到.NET 4.6的重要版本,它们各自在.NET框架的发展历程中扮演了关键角色,提供了丰富的开发工具和库,帮助开发者构建各种类型的桌面、Web和移动应用程序。无论是进行旧项目的...
本文将详细介绍.NET 4.0中并行性相关的三个关键概念:Parallel LINQ (PLINQ),Task Parallel Library (TPL) 和 Reactive Extensions (Rx)。 **Parallel LINQ (PLINQ)** PLINQ是并行查询语言,它是LINQ(Language ...
.NET Framework 4.0是微软开发的一个重要软件框架,它为开发者提供了构建、运行Windows应用程序所需的类库和服务。这个框架自2010年发布以来,已经成为许多Windows应用的基础,尤其是那些基于C#、VB.NET或其他.NET...
.NET Framework 4.0 是该框架的一个重要版本,它引入了许多新特性,包括但不限于改进的并行处理能力、增强的安全性和更好的性能优化。对于开发者来说,了解如何正确安装 .NET Framework 4.0 至关重要,尤其是在遇到...
下载并安装"NetFramework4.0.30319.exe"文件,即可将.NET Framework 4.0.30319添加到您的系统中,为运行依赖该版本的应用程序提供必要支持。请确保在安装前检查系统兼容性和任何可能的更新,以保证最佳的运行效果。...
.NET Framework 4.0 是一个重要的更新,引入了许多新特性和性能改进,如任务并行库(TPL)、动态语言运行时(DLR)以及改进的垃圾回收机制。对于那些使用 .NET 4.0 开发的应用程序,压缩包提供的 Net4.0 文件版本...
此版本引入了C# 4.0和VB.NET 10.0语言的更新,带来了动态类型、多语言互操作性(也称为“DLINQ”)和命名参数等新功能。此外,.NET Framework 4.0还包含了Windows Communication Foundation (WCF)、Windows Workflow...
5. 智能计算的定义之一是打破CPU处理复杂应用的边界,意味着在服务器集群中处理大规模并行计算任务。 6. GPU(图形处理器)通常用于视频图像处理和高性能计算(HPC)场景,例如HPC混合应用高吞吐量场景和HPC高性能...
.NET Framework 4.0的并行计算库(TPL)使得开发者可以轻松利用多核硬件的潜力,通过任务并行、数据并行和并发集合等功能实现高效的多线程编程。 8. **内存管理优化**: .NET 4.0改进了垃圾回收机制,减少了对...
总的来说,.NET 4.0的并行库提供了一套全面的工具,使开发者能够构建高性能的多线程应用,同时减少了对底层线程管理和同步的复杂性。然而,为了充分发挥并行编程的潜力,理解并考虑到数据竞争、上下文切换、任务调度...
此外,4.0版本引入了改进的性能和新的编程模型,例如并行计算支持,这使得开发者能够充分利用多核处理器的优势。 在文件列表中,"dotNetFx40_Client_x86_x64.exe"是.NET Framework 4.0的客户端版本安装程序,它包含...
10. **更新和维护**:安装完成后,保持.NET Framework 4.0的更新至关重要,以确保系统的安全性和稳定性。微软会定期发布安全更新和修复补丁,需要密切关注并安装。 总的来说,XP用户可以通过以上步骤安装.NET ...
《MyTools-V7.0(NET4.0)——基于.NET Framework 4.0的实用工具集合》 MyTools-V7.0是一款专为.NET Framework 4.0平台设计的实用工具集,它包含了多种功能丰富的工具,旨在帮助用户解决日常工作中遇到的各种问题。...