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

上述事实揭示了一

好的,我来为您生成使用MWORKS.SyslabJulia语法代码,实现加性高斯白噪声信道下FM通信系统的仿真: ```julia using MWORKS.Syslab # 参数设置 fs = 100e3 # 采样频率 100 kHz fm = 10e3 # 调制频率 10 kHz fc = 50e3 # 载波频率 50 kHz A = 1 # 载波幅度 duration = 0.01 # 信号持续时间 10 ms snr = 20 # 信噪比 20 dB # 生成消息信号 t = 0:1/fs:duration-1/fs message = cos(2π*fm*t) # FM调制 kf = 500 # 调频指数 deviation = kf * maximum(message) modulated_signal = A * cos.(2π*fc*t + 2π*kf*cumsum(message)/fs) # 添加高斯白噪声 noise_power = A^2 / (10^(snr/10)) noise = sqrt(noise_power/2) * (randn(size(modulated_signal)) + 1im*randn(size(modulated_signal))) received_signal = modulated_signal + noise # FM解调 demodulated_signal = diff(angle.(received_signal)) * fs / (2π*kf) # 绘制结果 figure(1) subplot(3,1,1) plot(t, message) title("原始消息信号") xlabel("时间 (s)") ylabel("幅度") subplot(3,1,2) plot(t, real(modulated_signal)) title("FM调制信号") xlabel("时间 (s)") ylabel("幅度") subplot(3,1,3) plot(t[1:end-1], demodulated_signal) title("解调后的信号") xlabel("时间 (s)") ylabel("幅度") suptitle("加性高斯白噪声信道下的FM通信系统仿真") ``` 这段代码实现了以下功能: 1. 设置系统参数,包括采样频率、调制频率、载波频率等。 2. 生成原始消息信号,这里使用了一个简单的余弦波。 3. 进行FM调制,包括频率偏移的计算。 4. 在信道中添加高斯白噪声。 5. 进行FM解调。 6. 绘制原始消息信号、调制信号和解调信号的时域波形。 通过这段代码,我们可以观察FM通信系统在加性高斯白噪声信道下的性能表现。解调后的信号与原始消息信号的比较可以让我们评估系统的抗噪声能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值