- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
最近比较闲,(项目要转Java被分到架构组,边缘化人员,无所事事 哈哈哈哈) 。
记录一下前段时间用到的.NET框架下采用并行策略充分利用多核CPU进行优化的一个方法 。
起因是项目中有个结算的方法,需要汇总一个月的数据在内存中进行计算,统计,分组 ,然后产生新的数据 。
在某个客户那部署后发现,这个方法执行的效率很低,监控发现数据从数据库查询出来 很快(因为数据库单独一台服务器) 。
然后通过top查看服务器的CPU就跑到了100%.内存正常,查了下CPU的型号 emm...很烂 但是好在核心很多(毕竟服务器级的U).. 。
查看服务器核心数 是在16个. Linux用top命令看的话,理论上CPU跑到1600%才算吃满,但是程序只吃了单个核. 。
等于1人干活 15人在吃瓜呀...如图
然后查看了代码,发现结算的计算这一块代码是在单个foreach中进行顺序计算,所以决定用.NET提供的并行任务库(TPL)进行优化. 。
优化完成后,从之前的结算直接导致线程超时异常 变成 大概在20秒左右就结算完成.获得了巨大的提升. 。
在硬件发展迅速的今天.有太多的个人电脑和服务器级CPU都拥有多个 CPU 内核,为了方便多个线程能够同时执行。 充分利用硬件,就可以利用并行编程对代码进行并行化,以将工作分摊在多个处理器上.
以前,并行化需要自行开启子线程,维护锁等各种繁琐操作。但是从 .NET Framework 4 中引入的TPL简化了并行开发。 我们只需要通过简单的修改,就可以编写高效、细化且可伸缩的并行代码,而不必直接处理线程或线程池.
下图是官方文档的截图,简单的说明了 .NET 中的并行编程体系结构
我们可以看到Parallel 就是在线程处理上加了一层封装好的算法,让我们处理并行多线程更简单 。
。
任务并行库 (TPL) 是 System.Threading 和 System.Threading.Tasks 空间中的一组公共类型和 API.
TPL 的目的是通过简化将并行和并发添加到应用程序的过程来提高开发人员的工作效率.
TPL 动态缩放并发的程度以最有效地使用所有可用的处理器.
此外,TPL 还处理工作分区、ThreadPool 上的线程调度、取消支持、状态管理以及其他低级别的细节操作.
通过使用 TPL,你可以在将精力集中于程序要完成的工作,同时最大程度地提高代码的性能.
(以上来自于官方文档,我觉得已经讲的很详细了) 。
那么接下来,我们就编写一个并行任务的示例,来看看效果
首先,并行任务库提供了两个方法 一个Parallel.ForEach 一个Parallel.For 用法都差不多,这里我们用Parallel.For做实验 。
先创建两个方法,代码如下
//创建顺序执行方法 static List<dynamic> AddModelSequential(int modelCount) { var list = new List<dynamic>(); //为了增加循环复杂性,里面嵌套一个循环 for (int i = 0; i < modelCount; i++) { int f = 0; for (int j = 0; j < 5000; j++) { f++; } list.Add(new { bbb = i, aaa = "1", ccc = f }); } return list; } //创建并行执行方法 static List<dynamic> AddModelParallel(int modelCount) { var list = new List<dynamic>(); Parallel.For(0, modelCount, i => { int f = 0; //为了增加循环复杂性,里面嵌套一个循环 for (int j = 0; j < 5000; j++) { f++; } list.Add(new { bbb = i, aaa = "1",ccc= f}); }); return list; }
。
接着执行两个方法,都跑10W条数据,并记录执行时间.如下
static void Main(string[] args) { Console.Error.WriteLine("执行顺序循环..."); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); AddModelSequential(1000000); stopwatch.Stop(); Console.Error.WriteLine("顺序循环时间(毫秒): {0}", stopwatch.ElapsedMilliseconds); stopwatch.Reset(); Console.Error.WriteLine("执行并行循环..."); stopwatch.Start(); AddModelSequential(100000); stopwatch.Stop(); Console.Error.WriteLine("并行循环时间(毫秒): {0}", stopwatch.ElapsedMilliseconds); Console.ReadLine(); }
本人是I9 12代CPU 逻辑处理器有20个,得到结果如图
性能提升20倍.. 。
由于在开发机上跑的东西比较多,对于CPU的使用情况,监控不是很清楚,我们掏出..阿里云99元包邮的2核2G的服务器..来看看效果. 。
我们可以明显看到在2核机上 性能大概也有接近一倍的提升 。
通过top命令,可以明显的监听到CPU的使用情况 。
在跑第一个循环的时候,CPU 100%,单核吃满,如图
跑第二个循环的时候,第2颗CPU就开始参与进来了,如图
所以在合适的情况下(注意,这里是合适的情况) 。
程序中采用并行任务库充分的利用服务器的多核性能可以使运行效率有很大的提升. 。
。
。
PLINQ 是 LINQ 的一组扩展 。
它允许在运行代码的计算机上使用多个处理器或内核对支持 IEnumerable<T> 接口的集合并行执行查询.
这可以显著减少处理大型数据集或执行复杂计算所需的时间 。
注意,这里可以看到 PLINQ只支持 IEnumerable的接口,所以linq to sql时的表达式树是不支持的,如果使用则会导致全表查询到内存中 。
使用方式也很简单,在数据集处理之前加上AsParallel方法即可,如下
//LINQ var results = from item in dataSource where item.SomeCondition() select item.SomeTransformation(); //PLINQ var parallelResults = from item in dataSource.AsParallel() where item.SomeCondition() select item.SomeTransformation();
。
PLINQ的使用场景比较特殊,目前demo中我还没反映出来比LINQ要快(甚至LINQ比PLINQ要快很多). 。
所以我们在用的时候一定要考虑到以下几点
综上所述,如果要用PLINQ一定要充分的进行测试与性能评估,一定要确定PLINQ有较大的提升时,才去使用. 。
。
. 。
。
最后此篇关于使用.NET并行任务库(TPL)与并行Linq(PLINQ)充分利用多核性能的文章就讲到这里了,如果你想了解更多关于使用.NET并行任务库(TPL)与并行Linq(PLINQ)充分利用多核性能的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
假设我有一个 DataTable。 var dt = getDataTable(); 然后我做 Parallel.For (0, dt.Rows.Count, i => Foo (dt.Rows[i]
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
对不起我的英语不好。所以,这是我的问题 我正在尝试通过 PLINQ 更新 DataTable 这是我的代码 DataTable table = new DataTable(); table.Colum
据我了解: Programming to leverage multicores or multiple processors is called parallel programming. 但是如果
我想对数据流执行查询,同时以一定程度的并行性并行处理项目。通常,我会使用 PLINQ,但我的工作项不受 CPU 限制,而是 IO 限制。我想使用异步IO。 PLINQ 不支持异步工作。 使用异步工作项
据我了解: Programming to leverage multicores or multiple processors is called parallel programming. 但是如果
在MSDN据说 PLINQ 不保留顺序。我想在我的项目中演示它,但我有一个问题,那就是始终保持秩序。我有一个收藏List> table这些是我的疑问: var linqQuery = table
我对 Plinq 和 Repo 模式还很陌生。我需要您提供一些引用资料和指南,以便在 fx 4.0 中使用 dbml、PLinq 实现存储库模式 最佳答案 存储库模式为您提供了对数据存储的抽象。如果带
假设您正在查询具有一百万条记录的集合,当您只有一个 CORE 处理器时,PLINQ 的性能是否与普通的 LINQ 查询有任何不同。 我知道 PLINQ 在多核处理器上工作得很好。只是想了解它在单个核心
我正在使用带有以下代码的 PLINQ: static void Main(string[] args) { var lt = new List() {1,2,3,4,5};
我正在尝试实现 PLINQ 示例但面临以下问题我的顺序查询比并行查询执行得更快。 这里是代码示例: Stopwatch sw = new Stopwatch(); in
下面是我在 Windows 服务中定期运行的示例 PLINQ 查询: var resultList = new List>(); try { resultList = emailsToSend
我写了一个 LINQ 来找出文本文件中唯一字符的频率。我还在 select 的帮助下将我的初始结果转换为一个对象。最终结果以列表的形式出现。以下是我使用的查询。 charNodes = inputSt
PLINQ 是否保证按照原始序列被操作的顺序返回查询结果,即使结果是并行产生的?例如: new List(){"a", "b", "c", "d"}.asParallel().Select(str =
许多自定义 Enumerable 扩展可以根据其他内置操作来实现 - 例如这个简单的便捷方法: public static bool AnyOf(this TElement item, IEnumer
我正在运行一个 PLINQ 查询,如下所示: ParallelQuery winningCombos = from n in nextComboMaker.GetNextCombo()
我遇到过静态构造函数中的以下 plinq 语句陷入僵局的情况: static void Main(string[] args) { new Blah(); } class Blah {
最近我对 Linq 和 Plinq 做了一些测量。我看不出 Plinq 在哪种情况下具有真正显着的优势。 我发现了很多例子,例如: Enumerable.Range(0, 10000).AsParal
PLINQ 作为 LINQ 的扩展被添加到 .NET 4.0 Framework 中。 这是什么? 它解决了什么问题? 什么时候合适,什么时候不合适? 最佳答案 这是并行 LINQ。这是一种在多核/多
产品中(基于ASP.NET MVC开发)需要经常对药品名称及名称拼音码进行下拉匹配及结果查询。为了加快查询的速度,所以我最开始就将其加入内存中(大约有六万五千条数据)。 下面附实体类。
我是一名优秀的程序员,十分优秀!