MWORKS.Syslab 如何统一 Julia、C/C++、Python 乃至 MATLAB —— 解密多语言统一的底层机制

科学世界蓬勃发展,注入了许多时代特有的活力。年轻理科生们的口中逐渐出现了诸如“调参侠”“调包小子”“炼丹师”等新潮的调侃词语,这些来自机器学习/深度学习领域的“梗”在社交网络中逐渐扩散,让人们不禁感叹科学计算已经成为了炙手可热的“显学”。

虽然科学计算正呈现大兴之势,但其内生的复杂性和综合性仍然导致生态分化严重。尽管Python和C/C++是主流方案,但该方案在科学计算领域并非万能;注重开箱即用的工程师们依然使用MATLAB和R,而追求抽象复用和语言底层能力的框架开发者们则热衷于折腾Julia。

同元软控MWORKS.Syslab是现代化统一科学计算环境,经多年综合权衡,底层选用性能/功能上限相对高的Julia语言,同时,集成诸如Python、M语言等现有科学计算生态。虽然MWORKS.Syslab使用Julia作为底层,但生态体量庞大的Python开发者也能平滑适应Syslab开发环境。在MWORKS.Syslab中,用户可以点击左上方“新建”按钮,轻松创建Python脚本进行开发,对于熟悉Python开发的用户,他们会发现MWORKS.Syslab移植了Python开发的常见工作流,其中一个不可忽视的关键特性是,在MWORKS.Syslab中,Python程序可以通过先进的“Seamless FFI”方式轻松访问 Julia 编写的 MWORKS.Syslab 函数库。

△ Syslab Python调用Julia案例

图中的TyPlot和TyMathCore其实是由Julia编写的图形库和数学库,然而它们如图被导入和使用时,看起来就像普通的Python库一样。这种方便的技术是如何实现的呢?

答案就是利用了前面所提到的FFI(外部函数接口)。FFI 技术用于实现不同编程语言间的相互调用,从而使上图中这种跨语言的兼容成为可能。正如上图所示,Syslab 通过FFI技术,实现了在Python中调用Julia编写的TyPlot和 TyMathCore。部分读者或许并不熟悉FFI,但其相关技术却无处不在,尽管整个科学计算生态错综复杂,但底层则是统一的:一个经典例子是 Fortran 编写的线性代数计算库,无论是 NumPy、PyTorch、Julia 还是 R,都依赖 FFI 技术调用这些 Fortran 库。

在解释什么是FFI以及MWORKS.Syslab做了什么有趣的事之前,我们不妨先看看这个领域的背景。

基于C语言的 FFI 技术,是科学计算领域统合多语言的基石。全球有成百上千种独特的编程语言,其中大部分都在其特定领域发挥着不可替代的作用。为了满足现实场景的复杂需求,我们常常需将多种技术整合在一块。因此,很多时候我们需要某种跨语言调用技术,以便同时使用多种编程语言来达成目的,而对科学计算领域来说,这个技术就是基于C FFI的多语言互调用。

我们常见的网络服务就是一种简洁的跨语言调用技术,但由于性能问题,该技术不适用科学计算领域。总的来说,网络服务端提供的服务可以被视为由服务器所用的编程语言导出的“函数”,来自网络的JSON数据则作为这些函数的“参数”。“参数”通过反序列化过程转化为相应语言能够理解的数据格式,然后被服务器提供的服务处理,这个过程就被视为“函数调用”。最后,函数调用的结果会被序列化为JSON数据,并反馈给客户端。在跨语言调用的意义上,客户端处理数据的过程与服务端是相似的。

虽然,基于网络服务的跨语言调用方案普遍适用于非科学计算领域。但对科学计算领域来说,情况则截然不同。

让我们看下图这个例子:

△Python远程调用:服务端/客户端

根据上图代码启动服务器,并在客户端运行10000次本地请求,运行时间超过20s。

根据上述实验可知,仅仅10000次基于网络的同步跨语言调用,Python的开销长达20s。熟悉Python底层的朋友都知道,Python的基础四则运算,性能基本在100 纳秒内,在网络调用中却退化到毫秒级,性能上相差四个数量级。这样的性能损耗,对于科学计算这样大部分都是低开销密集计算的场景来说,即使基于网络的跨语言调用再怎么方便,也无法满足要求。

实际上,在计算性能要求较高的场景中,传统的跨语言互调用方案通常采用的是“进程内互调用”的FFI技术,且通常是基于C的FFI技术。在这种方案中,C API成为了C FFI的核心概念。

C语言作为几乎所有编程语言的底层,有着一项特别的殊荣:绝大多数语言都提供一组C API,从而支持与C语言的进程内互操作。像Python这样有运行时的语言,以动态链接库的形式存在 (libpython.so),这些动态链接库导出一组完整的、能精细控制该语言的C函数符号;而像Rust这样没有运行时的语言,则由编译器直接生成二进制文件,其编译器支持按需导入或导出指定的C函数符号。上述C函数符号,以及对其调用方式、参数内存的约定,就是技术领域常说的C API。

△ Python Stable C API 例子:PyLong_FromSsize_t

上述事实揭示了一项普遍情况:绝大多数语言都支持导出C API,让外部语言操作自身;同时,它们也支持导入C API,以便操作其他外部语言。因此,从理论上来说,基于C API,任意两门编程语言都可以轻松相互调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值