为什么鼓励Julia的devectorization?

abe*_*ysh 14 multithreading vectorization julia

似乎在Julia鼓励编写devectorized代码.甚至有一个试图为你做这件事.

我的问题是为什么?

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

目前,编写快速代码的目标与简洁/清晰的代码之间似乎存在冲突.

其次,技术原因是什么?好吧,我明白量化的代码创建额外的临时等,但矢量化功能(例如broadcast(),map()等),具有多线程他们的潜力,我认为多线程的好处会超过临时工和其他缺点的开销矢量化函数使它们比常规循环更快.

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

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

Col*_*ers 14

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

朱莉娅背后的核心发展声明是"我们贪婪".核心开发者希望它能够做到一切,并且快速完成.特别要注意的是,该语言应该解决"双语问题",在这个阶段,看起来它会在v1.0命中时完成.

在您的问题的上下文中,这意味着您询问的所有内容要么已经是Julia的一部分,要么是为v1.0计划的.

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

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

关于多线程,当前正在为Julia实现本机多线程,我相信主分支上已经有一组实验例程.相关问题页面在这里.由于朱莉娅称之为BLAS,因此Julia已经在理论上提供了一些向量/矩阵运算的隐式多线程.我不确定它是否默认开启.

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

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


tho*_*oly 12

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

在其他地方,正如你所说,通过避免临时中间体,你可以从发展中受益:例如,如果x是一个向量,表达式

y = exp(x).*x + 5
Run Code Online (Sandbox Code Playgroud)

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

y = [exp(z)*z+5 for z in x]
Run Code Online (Sandbox Code Playgroud)

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

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

从长远来看,"足够聪明的编译器"可以通过自动开发这些操作中的一些来避免临时性,但这是一个更难的路径,对于不警惕的潜在陷阱,而不是看起来.

然而,你的"矢量化代码总是更简洁,更容易理解"的说法并非如此:在编写Matlab代码时,你必须走极端,想出一种实现简单操作的矢量化方式当考虑循环时.您可以在邮件列表中搜索无数的例子; 我记得在SO上的一个是如何使用Julia在矩阵中找到连通分量.

  • Hadamard产品没有BLAS例程(我知道),请参阅http://www.netlib.org/blas/.对于简单的操作,比如`axpy!`,原生的julia代码和BLAS一样快(更常见).总的来说,你不必担心这个问题,只需按你认为合适的方式编写代码即可.我总是首先编写简单而优雅的代码,并且仅在分析确定瓶颈后才担心加速. (2认同)