为什么鼓励Julia中的devectorization?

时间:2016-01-14 02:04:58

标签: multithreading vectorization julia

似乎在朱莉娅鼓励编写devectorized代码。 甚至有package试图为你做这件事。

我的问题是为什么?

首先,从用户体验方面来讲,矢量化代码更简洁(代码更少,然后错误的可能性更小),更清晰(因此更容易调试),更自然的编写代码的方式(至少对于某人而言)谁来自科学计算背景,朱莉娅试图迎合)。能够写出像vector'vectorvector'Matrix*vector这样的东西非常重要,因为它对应于实际的数学表示,这就是科学计算人员在脑海中想到它的方式(而不是嵌套循环)。而且我讨厌这样的事实,这不是写这个的最佳方式,并且将它重新分解成循环会更快。

目前,编写快速代码的目标与简洁明了的代码之间似乎存在冲突。

其次,这是什么技术原因?好吧,我理解矢量化代码会创建额外的临时代码等,但矢量化函数(例如,broadcast()map()等)有可能多线程化它们,我认为它的好处是多线程可以超过临时值的开销和矢量化函数的其他缺点,使得它们比常规循环更快。

Julia中的矢量化函数的当前实现是否隐含多线程?

如果没有,是否有工作/计划为向量化函数添加隐式并发并使它们比循环更快?

2 个答案:

答案 0 :(得分:14)

为了便于阅读,我决定将我的评论马拉松变成一个答案。

朱莉娅背后的core development statement是"我们贪婪"。核心开发人员希望它能够所有,并快速完成。特别要注意的是,语言应该解决"双语问题",在这个阶段,看起来它会在v1.0命中时完成。

在你的问题的背景下,这意味着你所询问的一切要么已经是Julia的一部分,要么是为v1.0计划的。

特别是,这意味着如果编程问题适用于矢量化代码,则编写矢量化代码。如果使用循环更自然,请使用循环。

到v1.0命中时,大多数矢量化代码应该比Matlab中的等效代码快或更快。在许多情况下,这个开发目标已经实现,因为Julia中的许多向量/矩阵操作被编译器发送到适当的BLAS例程。

关于多线程,目前正在为Julia实现 native 多线程,我相信主分支上已经有一组实验例程。相关问题页面为here。由于Julia称之为BLAS,因此对于某些向量/矩阵运算的隐式多线程已经在Julia中理论上可用。我不确定它是否默认开启。

请注意,在MATLAB中,许多矢量化操作仍然(目前)要快得多,因为MATLAB已经编写了多年的专用多线程C库,然后将其称为引擎盖。一旦Julia具有本机多线程,我希望Julia能够超越MATLAB,因为在那时整个开发社区可以搜索标准的Julia软件包并升级它们以尽可能利用本机多线程。

相比之下,MATLAB没有本机多线程,因此您依靠Mathworks以底层C库的形式提供专门的多线程例程。

答案 1 :(得分:12)

你可以 vector'*matrix*vector(或者如果您更喜欢标量输出,可以dot(vector, matrix*vector))。对于像矩阵乘法这样的东西,使用矢量化表示法要好得多,因为它调用的底层BLAS库比基本上任何语言/编译器组合生成的代码都更加优化。

在其他地方,正如您所说,您可以通过避免临时中间体来受益于启示:例如,如果x是一个向量,那么表达式

y = exp(x).*x + 5

创建3个临时向量:一个用于a = exp(x),一个用于b = a.*x,一个用于y = b + 5。相比之下,

y = [exp(z)*z+5 for z in x]

不会产生临时中间体。由于julia中的循环和理解很快,因此编写devectorized版本没有任何缺点,事实上它应该稍微好一点(特别是在适当的情况下使用@simd等性能注释)。

线程的到来可能会改变一些事情(使矢量化exp比“天真”exp更快,但总的来说我会说你应该把它视为一个“正交”的问题:julia可能会使多线程如此易于使用,以至于您自己可能使用多个线程编写操作,因此矢量化“库”例程仍然没有优于您自己编写的代码。换句话说,您可能使用多个线程,但仍然编写devectorized代码以避免那些临时代码。

从长远来看,"sufficiently smart compiler"可以通过自动开发一些这些操作来避免临时性,但这是一条更难的路线,对于粗心大意的潜在陷阱,可能看起来像。

你的声明“矢量化代码总是更简洁,更容易理解”然而事实并非如此:在编写Matlab代码时,你必须走极端,想出一种矢量化的写作方式当考虑循环时,实际上是简单的操作。您可以在邮件列表中搜索无数的例子;我记得的一个是How to find connected components in a matrix using Julia