编程语言的发展趋势及未来方向(6):并发

好,最后我想谈的内容是“并发”。

听说过摩尔定律的请举手……几乎是所有人。那么多少人听说了摩尔定律已经结束了呢?嗯,还是有很多人。我有好消息,也有坏消息。我认为摩尔定律并没有停止。摩尔定律说的是:可以在集成电路上低成本地放置晶体管的数目,约每两年便会增加一倍。有趣的是,这个定律从60年代持续到现在,而从一些迹象上来看,这个定律会继续保持20到30年。

摩尔定理有个推论,便是说时钟速度将根据相同的周期提高,也就是说每隔大约24个月,CPU的速度便会加倍──而这点已经停止了。再来统计一下,你们之中有谁的机器里有20GHz的CPU?看到了没?一个人都没有。但如果你从五年前开始计算的话,现在我们应该已经在使用20GHz的CPU了,但事实并非如此。这点在五年前就停止了,而且事实上最大速度还有些下降,因为发热量实在太大了,会消耗许多能源,让电池用的太快。

有些物理方面的基础因素让CPU不能运行的太快。然而,另一意义上的摩尔定理出现了。我们还是可以看到容量的增加,因为可以在同一个表盘上放置多个CPU了。目前已经有了双核、四核,Intel的CTO在三年前说,十年后我们可以出现80核的处理器。

到了那个时候,你的任务管理器中就可能是这样的。似乎有些吓人,不过这是我们实验室中真实存在的128核机器。你可以看到,计算能力已经完全用上了。这便是个问题,比如你在这台强大的机器上进行一个实验,你自然希望看到100%的使用状况,不过传统的实验都是在一个核上执行的,所以我们面临的挑战是,我们需要换一种写程序的方式来利用此类机器。

我的一个同事,Herb Sutter,他写过一篇文章,谈到“免费的午餐已经结束了”。没错,我们已经不能写一个程序,然后对客户说:啊,未来的硬件会让它运行的越来越快,我们不用关心太多──不,已经不会这样了,除非你换种不同的写法。实话说,这是个挑战,也是个机遇。说它是个挑战,是因为并发十分困难,至今我们对此还没有简单的答案,稍后我会演示一些正有所改善的东西,但……这也是一个机遇,在这样的机器上,你的确可以用完所有的核,这样便能获得性能提高,不过做法需要有所不同。

多核革命的一个有趣之处在于,它对于并发的思维方式会有所改变。传统的并发思维是在单个CPU上执行多个逻辑任务,使用旧有的分时方式、时间片模型来执行多个任务。但是,你想一下便会发现如今的并发情况正好相反,现在是要将一个逻辑上的任务放在多个CPU上执行。这改变了我们编写程序的方式,这意味着对于语言或是API来说,我们需要有办法来分解任务,把它拆分成多个小任务后独立的执行,而传统的编程语言中并不关注这点。

使用目前的并发API来完成工作并不容易,比如使用Thread,ThreadPool,lock,Monitor等等,你无法太好的进展。不过.NET 4.0提供了一些美妙的事物,我们称之为.NET并行扩展。它是一种现代的并发模型,将逻辑上的任务并发与我们实际使用的的物理模型分离开来。以前我们的API都是直接处理线程,也就是(上图)下方橙色的部分,不过有了.NET并行扩展之后,你可以使用更为逻辑化的编程风格。任务并行库(Task Parallel Library),并行LINQ(Parallel LINQ)以及协调数据结构(Coordination Data Structures)让你可以直接关注逻辑上的任务,而不必关心它们是如何运行的,或是使用了多少个线程和CPU等等。

下面我来简单演示一下它们的使用方式。我带来了一个PLINQ演示,这里是一些代码,读取XML文件的内容。这有个50M大小的popname.xml文件,保存了美国社会安全数据库里的信息,包含某个洲在某一年的人口统计信息。这个程序会读取这个XML文件,把它转化成一系列对象,并存放在一个List中。然后对其执行一个LINQ语句,查找所有在华盛顿名叫Robert的人,再根据年份进行排序:

Console.WriteLine("Loading XML data...");var popNames =(from e in XElement.Load("popnames.xml").Elements("Name")     select new     {Name = (string)e.Attribute("Name"),State = (string)e.Attribute("State"),Year = (int)e.Attribute("Year"),Count = (int)e.Attribute("Count")}).ToList();Console.WriteLine(popNames.Count + " records");Console.WriteLine();string targetName = "Robert";string targetState = "WA";var querySequential =    from n in popNames    where n.Name == targetName && n.State == targetState    orderby n.Year    select n;

我们来执行一下……首先加载XML文件,然后进行查询。利用PLINQ我们可以做到并行地查询。我们只要拷贝一份代码……改成queryParallel……现在我唯一要做的只是在数据源上使用AsParallel扩展方法,这样便会引入一套新的类型和实现,此时相同的LINQ操作使用的便是并行的实现:

var queryParallel =    from n in popNames.AsParallel()where n.Name == targetName && n.State == targetState    orderby n.Year    select n;

我们重新执行两个查询。

再次加载XML数据……并行实现使用了1.5秒,我们再试着运行一次,一般结果会更好一些,现在可能刚好在执行一些后台任务。一般我们可以得到更快的结果……这次比较接近了。现在你可以观察到,我们并不需要做太多事情,便可以在我的双核机器上得到并发的效果。

这里我无法保证说,我们只要随时加上AsParallel便可以得到两倍的性能,有时可以有时不行,有些查询能够被并行,有的则不可以。然而,我想你一定同意一点,使用如LINQ这样的DSL能够方便我们编写并行的代码,也更有可能利用起并行效果。虽然不是每次都有效,但是尝试的成本也很低。如果我们使用普通的for循环来编写代码,在某个地方使用线程池等等,便很容易在这些API里失去方向。而这里我们只要简单地尝试一下,便能知道是否可以提高性能了。

这里你已经看到我使用的LINQ查询,而现在也有很多工作是通过循环来完成的。你可以想象主要的运算是从哪里来的,很自然会是在循环里操作数据。如果循环的每个迭代都是独立的,便有很大的机会可以利用并发操作──我知道这里是“如果”,不过长期来看则一定会出现这样的情况。这时候便可以使用并行扩展,或者说是.NET并行扩展里的新API,把循环转化成并行的循环,只要简单的改变……几乎只要用同样的循环体把for重构成Parallel.For就行了。如果你有foreach操作就可以使用Parallel.ForEach,或是一系列顺序执行的语句也可以用上Parallel.Invoke。此时任务并行库会接管并执行这些任务,根据你的CPU数量使用最优化的线程数量,你不需要关注更深的细节,只需要编写逻辑就可以了。

就像我说的那样,可能你会有独立的任务但也可能没有,所以很多时候我们需要编程语言来关注这方面的事情。比如“隔离性(Isolation)”。例如,编译器如何发现这段代码是独立的,可以安全地并发执行,好比我创建了一个对象,在分享给其他人之前,我对它的改变是安全的。但是我一旦把它们共享出去了,那么它们便不安全了。所以如果我们的类型系统可以跟踪到这样的共享,如Linear Types──这在学术界也有一些研究。我们也可以在函数的纯洁性(Purity)方面下功夫,如关注某个函数是否有副作用,有些时候编译器可以做这方面的检查,它可以禁止某些操作,以此保证我们写出纯函数。还有便是不可变性(Immutability),目前的C#或VB,我们需要额外的工作才能写出不可变的代码──但本不该这样,我们应该在语言层面上更好的支持不可变性。这些都是在并发方面需要考虑的问题。

如果说有哪个语言特性超出这个范畴,我想说这里还有一个原则:你不该期望C#中出现某个特别的并发模型,而应该是一种通用的,可用于各种不同的并发场景的特性,就像隔离性、纯洁性及不可变性那样。语言拥有这样的特性之后,就可以用于构建各种不同的API,各种并发方式都可以利用到核心的语言特性。


原文链接:http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-6-concurrency.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/328221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GitLab创建项目 命令上传代码

注册哪里要验证点击图片 这里需要外网 有可能 右键gitbash 首次将本地创建项目推送远程代码仓库 touch readme.md 创建readme文件 git init 初始化git git status 查看修改状态 git add . 添加至本地仓库管理 git status 检查是否添加成功 git commit -am fir…

Linux ss 热点,在Linux系统下的ss命令(socket statistics)各种使用示例

本文演示在Linux操作系统下的ss命令(socket statistics)的各种使用示例。ss(套接字统计信息)是一个命令行工具,用于监视套接字连接并显示Linux系统的套接字统计信息。它可以显示PACKET套接字、TCP套接字、UDP套接字、DCCP套接字、RAW套接字、Unix域套接字等的统计信…

Jsoup代码解读之七-实现一个CSS Selector

转载自 Jsoup代码解读之七-实现一个CSS Selector当当当!终于来到了Jsoup的特色:CSS Selector部分。selector也是我写的爬虫框架webmagic开发的一个重点。附上一张street fighter的图,希望以后webmagic也能挑战Jsoup! select机制 Jsoup的se…

http1.1协议

HTTP/1.1协议 2018年01月04日 17:27:35 上杉绘梨衣- 阅读数 245 HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间数据交换的过程。 1.Http1.0和1.1 Http1.0:请求一次&…

ios刷android8.0,颤抖吧 iOS, Android 8.0正式发布!

原标题:颤抖吧 iOS, Android 8.0正式发布!如果现在选一个最好用的手机操作系统,多数人还是认为 iOS。不过最近几年,苹果和安卓的竞争越来越激烈,苹果的优势也越来越小。眼看 Android 8.0 就要来了&#xff…

编程语言的发展趋势及未来方向(5):元编程

动态语言的另一个关键和有趣之处在于“元编程”。“元编程”实际上是“代码生成”的一种别称,其实在日常应用中我们也经常依赖这种做法。观察动态语言适合元编程的原因也是件十分有趣的事情。 在这个蓝框中是一段Ruby on Rails代码(见上图)。…

Jsoup代码解读之六-parser(下)

转载自 Jsoup代码解读之六-parser(下)最近生活上有点忙,女儿老是半夜不睡,精神状态也不是很好。工作上的事情也谈不上顺心,有很多想法但是没有几个被认可,有些事情也不是说代码写得好就行的。算了,还是端正态度&…

编程语言的发展趋势及未来方向(4):动态语言

我下面继续要讲的是动态语言,这也是我之前提到的三种趋势之一。 我还是尝试着去找到动态语言的定义,但是你也知道……一般地说,动态语言是一些不对编译时和运行时进行严格区分的语言。这不像一些静态编程语言,比如C#,你…

android实现个税计算器,个税计算器2021 - 个人所得税计算器2021 -

一、征收范围特许权使用费所得,是指个人提供专利权、商标权、著作权、非专利技术及其他特许权的使用权取得的所得;其中,提供著作权的使用权取得的所得,不包括稿酬所得。 作者将自己的文字作品手稿原件或者复印件公开拍卖(竞价)取得…

系统架构师考试1

系统架构师备考经验 2018年03月23日 17:42:27 hongyinanhai00 阅读数 2911 系统架构师备考经验 距2017年11月份架构考试结束已经快半年了,自成绩出来以后就打算分享一下自己的备考经验,无奈搞IT的时间经常不能自由安排,这不刚提完离职终于…

java生成验证码并进行验证

一实现思路使用BufferedImage用于在内存中存储生成的验证码图片使用Graphics来进行验证码图片的绘制,并将绘制在图片上的验证码存放到session中用于后续验证最后通过ImageIO将生成的图片进行输出通过页面提交的验证码和存放在session中的验证码对比来进行校验二、生…

Jsoup代码解读之五-parser(中)

转载自 Jsoup代码解读之五-parser(中)上一篇文章讲到了状态机和词法分析的基本知识,这一节我们来分析Jsoup是如何进行词法分析的。 代码结构 先介绍以下parser包里的主要类: ParserJsoup parser的入口facade,封装了常用的parse静态方法。可…

html5实现3d翻页效果,利用css3 3d transform制作超逼真翻书效果

本教程给大家带来一个非常有创意的翻书效果,使用的是css 3D transforms属性和css transitions属性。这里将给你展示两种不同的图书设计:精装书和平装书。这两种设计只需要简单的改变一些css样式、图片和其他一些小细节就可以完成。注意: 并不是所有的浏览…

在.NET Core中使用MEF

题记:微软的可托管扩展框架也移植到.NET Core上了。 可托管扩展框架(Managed Extensibility Framework,MEF)是微软为大型应用程序(比如Visual Studio这样的东西)提供的一个功能扩展框架,通过一个…

系统架构师考试2

关于系统架构设计师考试的经验及建议 2017年11月12日 20:25:36 zhaoenweiex 阅读数 3162 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaoenweiex/article/details/78514716 前言 软考为广大技术人员提供了系统架构设…

html5圆形旋转菜单js,jquery 圆形旋转图片滚动切换效果

这个效果比较特别,可爱,所以在外面网站没怎么看到过,有兴趣的朋友可以下载后自己使用。PS: 经过修改已经兼容大众浏览器。效果图:在线演示:http://demo.jb51.net/js/ImagesRotateScroll/index.htmlStep1. 创建HTMLStep2. 创建CSS#…

Jsoup代码解读之四-parser(上)

转载自 Jsoup代码解读之四-parser(上)作为Java世界最好的HTML 解析库,Jsoup的parser实现非常具有代表性。这部分也是Jsoup最复杂的部分,需要一些数据结构、状态机乃至编译器的知识。好在HTML语法不复杂,解析只是到DOM树为止,所以…

在Linux和Windows的Docker容器中运行ASP.NET Core

译者序:其实过去这周我都在研究这方面的内容,结果周末有事没有来得及总结为文章,Scott Hanselman就捷足先登了。那么我就来翻译一下这篇文章,让更多的中文读者看到。当然Scott遇到的坑我也遇到了。 不过首先,对于不熟悉…

java反射机制的原理与简单使用

一、 原理 简单的来说,反射机制其实就是指程序在运行的时候能够获取自身的信息。如果知道一个类的名称/或者它的一个实例对象, 就能把这个类的所有方法和变量的信息(方法名,变量名,方法,修饰符,类型&#x…

架构师考试3

软考系统设计架构师经验与教训分享 2017年08月01日 17:20:29 leixiang831257 阅读数 18558 系统架构设计师考试经验和教训分享 但愿你是计算机专业的学生,考这个证,有助于提升你的综合能力,但是如果想通过考这个证,就能拿几十万…