写点什么

.NET 4.5 中任务并行类库的改进

  • 2011-12-08
  • 本文字数:1734 字

    阅读完需:约 6 分钟

微软正在努力改进.NET 4.5 中应用程序的性能,特别是使用任务并行类库(Task Parallel Library)的那些应用。接下来我会带你预览将要完成的改进内容:

Task, Task

.NET 并行编程 API 的核心是 Task 对象。对于这样重要的类,微软想法设法保证它要尽可能小。Task 的大多数属性都没有保存在类本身之中,而是保存在另一个名为 ContingentProperties 的对象中。这个二级对象会在程序需要的时候才创建,这样就会降低大多数一般情况下的内存占用。

.NET 4.0 发布的时候,最常见的情形是分支合并(fork-join)样式的编程,就像我们在 Parallel.ForEach 和 Parallel LINQ 中看到的那样。然而,有了.NET 4.5 和其中引入的异步机制,顺序样式的编程就取而代之,占据主导地位。微软非常确信这会是主要的方式,因此他们把 ContinuationObject 移动到 Task 中,把其他字段移动到 ContingentProperties 中。这使得顺序结构的代码运行更快,而 Task 对象的规模更小。

Task 也避免了一些不需要的等待。它最初拥有四个属性,但是 Joseph E. Hoag 解释说

由于我们进行了一些很聪明的结构调整,结果只有 m_result 字段才是真正必要的。通过对已经存在于基本的 Task 类中的字段重新利用,我们可以废弃 m_valueSelector 和 m_futureState 字段,而存储在 m_resultWasSet 中的信息可以存储在基本类型的上述状态标识中。

结果创建 Task所需的时间会减少 49-55%,对象的大小会减少 52%。

Task.WaitAll, Task.WaitAny

试想一下,我们需要同时等待十亿个任务。在一台 x64 的计算机上,这会导致 12,000,000 比特的负载,这还没有计算任务本身。如果使用.NET 4.5,负载会降到仅仅 64 比特。同时 WaitAny 的负载也会从 23,200,000 比特降到 152 比特。

之所以出现如此戏剧化的效果,是因为微软改变了使用核心同步基元(kernel synchronization primitives)的方式。在之前的版本中,每个任务都需要一个基元(primitive )。现在已经大大减少,每个等待操作只需要一个基元,与操作中的任务数量无关。

ConcurrentDictionary

在.NET 中,只有引用类型和很小的值类型才能够以原子的方式赋值。较大的值类型——像 Guid——则无法以原子的方式读写。在.NET 4.0 中,为了解决这个问题,ConcurrentDictionary 会使用 node 对象,每次与键值关联的值发生改变的时候,都会重新创建这个对象。在.NET 4.5 中,只有在无法以原子的方式对值进行写操作的时候,才会创建新的 node 对象。

另一项改变是我们可以动态地创建锁。 Igor Ostrovsky 写到

在实践中,为了达到最大吞吐量,往往需要大量锁。另一方面,我们又不希望分配太多锁对象,特别是在 ConcurrentDictionary 最后只存储了很少项目的时候。

想要提升性能,就要减少内存分配

Joseph 写到:

在我们的评测结果中你可以看到,在测试中分配的内存数量和完成测试所需的时间之间有直接关系。当我们单独查看的时候,内存分配并不是非常昂贵。但是,当内存系统只是偶尔清理不使用的内存时,问题就出现了,并且问题出现的频率和要分配的内存数量成正比。因此,你分配越多的内存,对内存进行垃圾回收的频率就越频繁,你的代码性能就会变得越差。

想要降低内存使用,一种方式就是避免使用闭包(closure)。不要在匿名的函数中捕获局部变量,我们可以把它传递给 Task 的构造函数,作为它的“状态(state)对象”。从.NET 4.5 开始,Task.ContinueWith 也会支持状态对象。

另一种减少内存使用的技术是缓存经常使用的任务。例如,假设一个函数会接受一个数组作为参数,并返回 Task。因为对于空数组结果总会是一样的,所以缓存代表空数组的 Task 就很合理。

下一个技巧是避免让任务不必要地“膨胀”。当某些代码触发了创建 ContingentProperties 的操作,Task 对象就会膨胀。最经常出现的原因包括:

  • 创建的任务带有 CancellationToken
  • 任务是从非默认的 ExecutionContext 创建的
  • Task 作为父 Task 参与到“结构化并行机制(structured parallelism)”中
  • Task 以 Faulted 状态结束
  • Task 通过 ((IAsyncResult)Task).AsyncWaitHandle.Wait() 处于等待状态

大家还要记住,任务膨胀并不一定是坏事。它只是需要注意的问题,这样我们就不会做不需要的事情,像传入从来不会用到的 CancellationToken 等。

查看英文原文: Task Parallel Library Improvements in .NET 4.5

2011-12-08 01:043283
用户头像

发布了 340 篇内容, 共 131.8 次阅读, 收获喜欢 13 次。

关注

评论

发布
暂无评论
发现更多内容

极狐GitLab 企业级 CI/CD 规模化落地实践指南(一)

极狐GitLab

DevOps cicd runner template Component

火山引擎DataLeap的Data Catalog系统公有云实践

字节跳动数据平台

大数据 数据中台 企业号 8 月 PK 榜

因为私域流量运营,App重新受重视?

FinFish

小程序生态 私域运营 小程序容器 私域流量运营 流量运营

断点续传的未来发展趋势与前景展望

镭速

断点续传 文件传输软件

极狐GitLab 上新:跳过无需备份项目,节约数 10 至 1000 倍时间与磁盘空间

极狐GitLab

DevOps gitlab 磁盘空间 数据备份恢复 备份时间

聊聊JDK1.0到JDK20的那些事儿 | 京东云技术团队

京东科技开发者

Java jdk jdk8 jdk17 企业号 8 月 PK 榜

从零开始学极狐GitLab|03 Runner 裸机部署

极狐GitLab

DevOps gitlab cicd SaaS DevSecOps

DTCC 2023即将启幕 明天见!

酷克数据HashData

实战:工作中对并发问题的处理 | 京东物流技术团队

京东科技开发者

数据库 并发 数据库锁 更新丢失 企业号 8 月 PK 榜

相约天津!全国智能汽车竞赛百度创意组总决赛通知

飞桨PaddlePaddle

百度 paddle 百度飞桨 飞桨国赛 全国大学生智能汽车竞赛

19. 第三方库的管理和虚拟环境

茶桁

Python pip conda

2023城博会|上海国际智慧工地展览会

AIOTE智博会

城博会 上海城博会

突破大模型 | Alluxio助力AI大模型训练-成功案例(一)

Alluxio

机器学习 gpu 模型训练 大模型 AIGC

浅谈统一权限管理服务的设计与开发

百度Geek说

百度 数据中心 企业号 8 月 PK 榜 权限服务

分布式事务的华丽进化 | 京东物流技术团队

京东科技开发者

分布式事务 数据库事务 企业号 8 月 PK 榜 柔性分布式事务

一文预览 | 8 月 16 日 NVIDIA 在 WAVE SUMMIT深度学习开发者大会 2023精彩亮点抢先看!

飞桨PaddlePaddle

人工智能 百度飞桨 WAVE SUMMIT

洛阳等级保护测评机构有哪些?在哪里?咨询电话多少?

行云管家

等保 等级保护 等保测评 洛阳

MySQL 执行计划详解 | 京东物流技术团队

京东科技开发者

MySQL 数据库 explain关键字 企业号 8 月 PK 榜

企业文件外发系统必备八大要素

镭速

文件外发系统

SAM适配下游任务的探究:SAM Adapter

华为云开发者联盟

人工智能 华为云 华为云开发者联盟 企业号 8 月 PK 榜

华为云GaussDB(for Influx)单机版上线,企业降本增效利器来了

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 8 月 PK 榜

GeaFlow任务能力增强:通过API定制流图计算逻辑

TuGraphAnalytics

分布式计算 java编程 API 图计算 tugraph

小灯塔系列-中小企业数字化转型系列研究——知识管理测评报告

向量智库

百度百舸平台的大模型训练最佳实践

Baidu AICLOUD

容错机制 大模型训练 异构计算 CheckPoint

本地工具是什么意思?本地工具与远程工具一样吗?

行云管家

IT运维 远程工具 本地工具

CCF C³ 走进百度:大模型与可持续生态发展

飞桨PaddlePaddle

人工智能 百度飞桨 文心大模型 重磅活动

MT7915 with IPQ4019/IPQ4029 5G Radio Achieve 843 Mbps Throughput|DBDC Network Card

wallyslilly

IPQ4019 ipq4029 MT7915

Programming abstractions in C阅读笔记p111-p113: boilerplate

codists

面试涨薪神奇操作,直接多给3k的JVM垃圾优化笔记

小小怪下士

Java 程序员 JVM 调优

aspera替代方案:探索这些安全且可靠的文件传输工具

镭速

aspera替代方案 文件传输工具

18. Python中的模块与包

茶桁

Python

.NET 4.5中任务并行类库的改进_.NET_Jonathan Allen_InfoQ精选文章