Julia语言:让高性能科学计算人人可用

摘要:一群科学家对现有计算工具感到不满:他们想要一套开源系统,有C的快速,Ruby的动态,Python的通用,R般在统计分析上得心应手,Perl的处理字符串处理,Matlab的线性代数运算能力……易学又不让真正的黑客感到无聊。

Julia是个灵活动态的语言,最初针对数值计算而发明,项目起初是MIT的研究课题,现已发展成富有活力的软件系统,也是目前最受关注的编程语言之一。日前,Julia的四位发明者Jeff Bezanson、Stefan Karpinski、Viral B. Shah、Alan Edelman接受了《程序员》杂志的专访。

让高性能科学计算为人人所用

《程序员》:你们因何设计Julia?想要解决的问题或达成的目标是什么?

Alan:对我来说,首要的问题是让高性能科学计算能为世界上的每一个人所用。我时时想着这一目标尚未完全实现,但Julia的出现使问题的解决成为可能。

我对并行计算的兴趣始于1988–1989年间在Thinking Machines工作时,Thinking Machines的产品是新潮的Connection Machine。2003年12月,Viral跟Parry Husbands等人一起凭借我们的Star-P并行MATLAB软件在MIT创业大赛中获胜。受此鼓舞,我创立了Interactive Supercomputing公司,从2004到2009年,公司做得风生水起。

在ISC,Parry、Viral和我认识到,通过一种慢速的动态专有语言来实现快速的并行化是荒唐的。Jeff也是ISC的员工,在这个问题上也有自己的独到见解。我真心希望看到这个问题的解决方案。

我永远不会忘记,那是2009年3月,我们要在办公楼的停车场上拍最后的团队合影,拍照花了很长时间,晚些时候Jeff和我就在停车场里走了走,在那里我们商定了Jeff来MIT做这个方案。

Jeff:科学计算语言中你所看到的特性通常都很复杂。多数系统中这些特性都是“内置魔术”——通过编译器和解释器内部的客户逻辑来实现,难于修改或扩展。我想看到一种更加全面的、可扩展的方法来实现这类功能。

Viral:我一直对科学计算感兴趣,这也是我的博士研究方向。我和Alan Edelman,以及我的导师John Gilbert一道,致力于构造一套并行的MATLAB。当时我同一些数学家、物理学家、化学家和生态学家一起负责几个科学应用,将他们的程序并行化以提高性能。在此过程中,有一件事变得清晰起来,那就是问题不在于并行化,而在于现有的语言根本没有足够的表达力。这些语言的设计使之难于实现高性能。很多这样的语言都由一些非计算机科学家设计,他们脑子里想的多是生产率而不是编译器设计。Julia团队的独特之处在于,我们四个人组合了多种学科——语言设计、数学和工程。结果我们便拥有了一种不仅为科学家和工程师喜欢,也为计算机科学家喜欢的语言;在我看来这是罕有的事情,对此我们都倍感幸运。

Stefan:读研时我真正想做的是程序语言设计,结果却进了网络研究实验室。到离开UCSB之前,我在用线性代数、机器学习和数据统计做网络流量的分析与建模。这需要一种弗兰肯斯坦式的编程语言组合:用于网络跟踪处理的C,准备数据的SQL,线程代数和机器学习的MATLAB,统计分析和视觉化的R,然后Ruby管理这一切。我的时间更多花在了查找问题,而不是做有用的工作上。

Viral和我在同一部门,常年一起玩“终级飞盘”。有一天我扔着盘片发泄着心中不快:这类工作的工具真是一团糟糕。Viral对我说:“我认识一个人,你可以跟他聊聊。”第二天他就通过Email把我介绍给了Jeff。我们便开始讨论用于数据分析的理想编程系统应该是怎样的。后来我们决定着手做点什么——以三个月为限,届时我们将决定是否继续。我完成了第一次git提交,搭好了服务器,并为Jeff和Viral开放了权限。Jeff提交了一个语法分析器,以及随后一个简单的解释器,Viral开始用新的语言写些代码。起初错误不断,速度也奇慢——但我们已可以用它做些事情,玩一玩语言的语法和语义。三个月来了又去了,我们完全没有停下的想法。

就在那无人察觉的三个月期限前后,Alan开始为MIT的Jeff提供资金支持。那时我们已把项目命名为Julia了。如今我们在MIT有一个完整的研究小组专注于基于Julia的高效率、高性能并行计算。

《程序员》:Julia这个名字有典故吗?

Alan:许多人问过这个问题。事实证明这个名字很棒,部分是因为每个人都有自己的解读理论。

Jeff: 给语言起名字着实不易。很高兴我们能有一个好听又好记的名字。

Stefan:坊间传言那是我的中名。对这一说法,我不能确认也不能否认。

《程序员》:能否介绍一下你们的背景?之前有语言设计方面的经验吗?

Jeff:语言本来是我主要的业余爱好。业余时间我便做一些语言设计和解释器方面的工作。我从互联网上了解到了Interactive Supercomputing公司,我意识到如果能去那儿工作,就可能获得少有的专业的程序语言方面的工作机会,于是便投了简历。我在那里大多数时间都在做一种针对.NET平台的编译器。

Viral:我从读博时就认识Alan,那时我们在加州大学Santa Barbara分校,与MIT的团队合作研发Star-P。毕业后我到Interactive Supercomputing公司工作,在那里认识了Jeff。不久后微软买走了这家初创公司,我们便琢磨接下来该做什么。

Stefan:我依然清晰地记得假期里造访瑞典亲人的家,在海滩上阅读《Programming Language Pragmatics》(中译本《程序设计语言——实践之路》),并因此被表弟温言揶揄的情形。不过我后来没有去做编译器,而是无意中走入了之后称为“数据科学”的领域。那时我正好有一堆数据,想搞清楚数据背后的含义。然而,作为一名数据科学家,我始终关注着语言设计方面。对我来说,编程语言绝不只是可以替换的工具。我相信更好的语言能让我们成为更好的程序员,使我们能解决更困难的问题。

《程序员》:谈到Julia时,很多文章开篇就会提起它的性能。科学计算语言的性能是一种不可替代的优势吗?

Stefan:对很多人来说,Julia的性能是一个大卖点。但不是说性能打倒一切,否则我们都去手工编写SIMD和GPU代码了。

Jeff:性能分两类:尝试一种方案时首次获得的性能和大量努力后获得的性能。我相信前者更为重要,且只要专注于前者,就算不能取得最佳的绝对性能,方案也能有效。

Viral:我来分享我做过的另一个开源项目——Circuitscape中的一个故事吧。我和同事Brad McRae开始时可以在10分钟内解决一个100结点的问题。如今,Circuitscape用户每天都能在几分钟内解决拥有数百万结点的问题。我们组合使用了更好的语言、更好的库以及更好的算法,达成了这一结果。现在的Circuitscape是用Python写的,我们正在试验通过用Julia重写来实达到更高规模的可能性。性能不是唯一考量,但对于一种科学计算语言,它肯定是最重要的方面之一。

《程序员》:除了高性能,Julia还有哪些与众不同的特性?

Jeff:Julia基于多分派(multiple dispatch)。这是一种强大的面向对象编程机制,以前其他语言也用过,但出于某些原因从未真正流行起来。我们设计的多分派旨在定义具有多种形式和行为的数学函数,事实证明它也能用于其他情形。它在“你能表达什么”和“编译器能用它做什么”之间达到了很好的平衡。

Viral:对我来说,Julia最好的方面不是某种语言特性,而是我们终于有了一个平台,在这里来自计算机科学、物理科学、社会科学以及数学领域的专家正在走到一起,创造从未有过的神奇。而这些原来不相往来的社区之间的合作在科学计算方面释放了新的可能性。

《程序员》:目前Julia最适合哪些场景的应用?

Jeff:Julia是真正的通用语言。总体上,我认为要改善一种语言就要使之更通用,而不是更适于某一种任务。但目前Julia最佳的应用案例是探索性计算(exploratory computing):试验不同的算法或尝试理解数据。模拟也是一个大用例:简洁地描述一套系统,同时获得尽量高的性能。目前,人们也在使用Julia开发GUI应用和小型的Web应用,但我们并没真正针对这种应用而设计。

Viral:Julia足以胜任的领域之一是教育。下一代学生可以直接跨过现有的技术。IJulia图形化的Notebook集成(运行Julia的IPython Notebook)使之对于教学极具魅力。研究者、算法开发者和库作者也在采用Julia,因为Julia使工作更高效。

《程序员》:在开发过程中,哪一部分投入的精力最多?现在最大的挑战是什么?

Jeff:越来越多的时间都花在考虑设计决定,以及为需要完成的工作排优先级上面了。 我们现在面临的一大挑战是随着可用包越来越多、越来越大,用户也需要将越来越多的代码加载到他们的环境中。Julia是设计成即时编译的,在运行时编译这么多代码已经开始影响速度了。我们正在寻求解决方案,情况应该很快会有改观。

Viral:设计良好的API需要相当长的时间。尽管Julia已很快,但我们还需要使它更快,而且更好地并行工作。关于哪些功能留在Base库中,哪些进入包中的决定也很艰难,因为像Julia这样的语言往往拥有很大的科学计算库作为基础库发布。尽管Julia已是一种可以随时安装的相对方便的科学计算工具,我们还需要在Julia及其生态包的安装方面做更多简化。

《程序员》:在Julia的设计过程中,你们遵循哪些原则?

Jeff:我们经常引用的一条原则是“做性能开销不大的最有价值的事”。我们愿意牺牲一些性能来换取更可靠、更易编写的程序,但也有限度。性能降低2倍?可以。10倍?不行。过去,这方面做了很多错误的妥协——例如,C和C++为了在这儿那儿省下一条指令,不惜为用户带来大量问题。

Viral: 我们始终考虑编程的便捷。让语言成为动态的很重要,但也要有些限制,从而类型推导可以起作用。这样就可能产生快速的代码,而不致麻烦用户声明所用的每个变量的类型。用户开心了,编译器的作者也开心了。

《程序员》:Julia的核心开发者和用户分别有多少?社区如何运作?

Jeff:我们的开发都通过GitHub进行,现在上面的代码贡献者有200名左右,稳定的、高度活跃的贡献者约有30名。我们在GitHub的issues和pull requests,以及邮件列表上都有大量讨论。我们喜欢听到大量观点,并在决策之前达成一致。

Viral:我听说过一种度量方法,社区的规模是邮件列表规模的10倍,基于此,估计Julia至少有10000名用户。我们努力打造一个尊重不同意见、同时为新用户提供方便的社区。这样才能吸引其他人,并使我们的工作有趣。

《程序员》:用Julia写的项目中,哪一个让你们觉得印象最深刻?

Jeff:绘图包Gadfly让人感觉很棒。还有JuMP,把描述优化问题的语言嵌入一种通用的语言中,这是最好的例子之一。它可以匹敌专用语言的性能。

IJulia也是精华。它提供了一个基于IPython Notebook的Web浏览器前端,是通过终端与机算机交互的最佳方式。

我特别喜欢的还有Quake 2渲染引擎(https://github.com/jayschwa/Quake2.jl)。

Viral:Julia的统计计算能力最棒,此类程序几乎完全用Julia写成,并将Julia引到一个出乎原有规划的方向上。当我们看到来自R社区的人们能将他们想要的功能开发成一个纯粹的包,而不需要任何语言上的修改,我们就知道语言的设计是正确的。

《程序员》:Julia足够稳定能用于生产环境了吗?

Alan:是的——我每天早饭前都运行蒙特卡洛模拟,通常是在60个核上。

Jeff: 尽管我们未能提供想要的所有特性,人们有时还会惊诧于一切在整体上竟运行得如此平稳。

Viral: 这取决于“生产”的含义。Julia是极好的教学工具,MIT及其他大学的许多课程已经在用它了。研究者也在工作中每天使用。如果“生产”指的是有企业支持的大型服务器上长期运行的任务,那么答案是否定的。

《程序员》:在整个开发和设计过程中,有没有想和其他开发者分享的体会?

Jeff:最初人们对新的编程语言往往持怀疑态度,这很正常。但事实证明,只要做出让几个早期的采用者觉得足够有趣的东西,你便能获得助力。

Viral:起初我也怀疑是否真正需要一种新的编程语言,是否所有的东西都不需要。但我已经学会拥抱新的语言(更多地来自科学计算背景的),这种多样性和试验过程都是好事。世界就是这样进步的,让旧思想的精华融入新思想。

《程序员》:有没有来自用户的意外收获或反馈?

Alan: 我每天清晨起来看到Julia中新加的东西都要吃上一惊。

Jeff:听说Julia被用于前沿的研究项目时我着实高兴了一把。少数研究团体让他们的实验室转变为使用Julia为主。哪怕有人只是尝试用Julia做一个真正有趣的应用,也让人兴奋。

《程序员》:对于初学者来说,学习Julia最困难的部分是什么?Julia中有哪些常见的陷阱?

Jeff:我们努力避免陷阱。我想可能出现的一个陷阱是全局和局部变量非常不同。全局变量更像字典,可以通过名字查询,也可以四处修改它。局部变量则完全不同,因为在很多情形中它们会被编译器完全优化掉。

Viral:最常见的陷阱在于有时人们期望Julia是MATLAB的零成本替代品。实际上它们有很多语法差异,有时它会绊倒一个有着多年MATLAB背景的用户。当然,一些旧的习惯并不容易忘掉。

《程序员》:与其他科学计算语言(例如Mathematica、MATLAB等)相比,Julia的劣势是什么?

Alan:在MIT,我们发现学生和年轻人乐于拥抱Julia,而有经验的教职员则跟进得慢一些。

Jeff:许多情况下,库比语言更重要。有许多对特定应用非常重要的库函数我们还没有提供。幸运的是调用C甚至Python很容易。

Viral:我们需要一个调试器。我们需要一个更加用户友好的性能分析工具。我们需要更多的库。我们需要更多用户。

《程序员》:你们有没有从科学计算语言的演化中看到一些趋势?从你们的角度来看,什么才是理想的科学计算语言(或系统)?

Alan:我相信Julia解放了科学计算,并将继续如此。 我观察过专家们通常用FORTRAN写的算法,感受则是人们不能碰这些算法。修改的难度注定了这一点,且主要从心理上。在一个人人可以调整算法进行试验的世界中,新创造将自由流淌。这是我最想看到的。

Jeff:长期以来我们看到语言系统中不断增强的运行时灵活性。渐渐地,人们拥抱了动态内存分配、动态连接,然后是动态分派(如OOP)、垃圾回收和即时编译。

Viral:我们的博客文章“为什么选择Julia”说的正是这个问题。除此以外,编程语言实验中还有一个有效使用多核和GPU的趋势。


你可能感兴趣的:(互联网的过去,现在,未来)