简介

Julia 是一个面向科学计算的高性能动态高级程序设计语言。其语法与其他科学计算语言相似。在许多情况下拥有能与编译型语言相媲美的性能。Julia 是个灵活的动态语言,适合科学和数值计算,性能可与传统静态类型语言媲美。

引用自百度百科.

Julia下的深度学习应用,以及其与Matlab、PyTorch的对比,请参考本人另外一篇博客Julia深度学习

安装与配置

Windows下下载安装包,双击按照提示安装即可,注意选择添加到环境变量. Linux下下载压缩包,解压然后添加环境变量即可. 以Ubuntu系统为例, 从官网下载Linux下的压缩包Generic Linux on x86, 下载下来的文件类似于 julia-1.7.2-linux-x86_64.tar.gz, 将其放到想安装的目录(记为JULIA_HOME), 执行命令tar -xzvf julia-1.7.2-linux-x86_64.tar.gz解压.

输入gedit ~/.bashrcPATH环境变量中添加值JULIA_HOME/julia-1.7.2/bin/. 重新打开一个终端, 输入julia, 则可以进入下图所示交互式解释器(REPL)界面
在这里插入图片描述

至此安装完成!

包的管理

安装与删除包

  • 安装包(方式1): 在REPL界面输入import Pkg; Pkg.add("XXX")
  • 安装包(方式2): 在REPL界面按]键进入包管理器界面, 输入add XXX安装
  • 删除包(方式1): 在REPL界面输入import Pkg; Pkg.rm("XXX")
  • 删除包(方式2): 在REPL界面按]键进入包管理器界面, 输入rm XXX(移除)

导入和使用包,略有不同, 如下图

在这里插入图片描述

# 方式一
import Plots
Plots.plot

# 方式二
using Plots
plot

设置代理与更换镜像

如果你需要设置代理才能上网, 则需要为Julia设置代理, 打开~/.julia/config/startup.jl文件(不存在则新建), 添加如下代码,重启Julia的REPL

ENV["HTTP_PROXY"]="http://xxx:port"

如果发现下载安装包比较慢, 则需要为Julia设置新的镜像, 打开~/.julia/config/startup.jl文件(不存在则新建), 添加如下代码,重启Julia的REPL

ENV["JULIA_PKG_SERVER"]="https://mirrors.bfsu.edu.cn/julia/"
# ENV["JULIA_PKG_SERVER"]="https://mirrors.tuna.tsinghua.edu.cn/julia"

离线安装包

离线安装包需要在能够联网的机器上,从GitHub上下载包, 具体包的地址,可以根据包的名称到这里查看. 在安装第三方包前,需要先安装General, 通过 git clone https://github.com/JuliaRegistries/General.git 下载General仓库, 放到任意位置, 进入General所在根目录, 在该目录下打开终端,进入Julia的REPL, 然后键入 ]进入包管理器界面.

接着输入 registry add General 来安装, 执行完成后可以在用户目录(~/.julia/registries/)下看到General.

(@v1.7) pkg> registry add General
     Cloning registry from "/home/liu/General"
       Added registry `General` to `~/.julia/registries/General`

下面以安装用于读写.mat的库为例, 从这里可以看到其依赖以下库: BufferedStreams, HDF5, SparseArrays, LinearAlgebra, Libz, CodecZlib

在这里插入图片描述

由于依赖较多, 而且每个依赖又会依赖其它包, 故这里通过非离线方式安装MAT的依赖包,然后以离线方式安装MAT包. 在GitHub中搜索相应的包名, clone 带有 .jl后缀的, 比如 MAT.jl, 在克隆的MAT.jl的根目录进入Julia的REPL, 按]进入管理界面, 然后输入 add .MAT.jl即可, 安装完成, 通过 using MAT 即可使用其中的函数, 如 matread, matwrite 等等, 如下.
在这里插入图片描述

性能测试

  • 硬件测试环境
    • CPU: Intel® Xeon(R) E5-2696 v3
    • 内存: 62.8 GiB
  • 软件测试环境
    • 系统: Ubuntu16.04LTS
    • 语言版本: Matlab2020, Python3.6, Julia-1.7.2,

话不多说,直接上代码与测试结果.

矩阵乘法代码如下
矩阵乘法代码
矩阵求逆代码如下
矩阵求逆代码
FFT代码如下
在这里插入图片描述

需要注意的是:Julia中FFTW库中的fft函数, 如果不指定维度, 则默认对所有维进行傅里叶变换, 测试结果如下表(单位s)

算法MatlabPythonJulia
乘法( 10240 × 10240 , N i t e r = 10 10240\times 10240, N_{\rm iter}=10 10240×10240,Niter=10)51.566468.070478.2974
求逆( 10240 × 10240 , N i t e r = 10 10240\times 10240, N_{\rm iter}=10 10240×10240,Niter=10)100.5972142.6631152.7482
乘法( 1024 × 1024 , N i t e r = 1000 1024\times 1024, N_{\rm iter}=1000 1024×1024,Niter=1000)6.39059.09619.5913
求逆( 1024 × 1024 , N i t e r = 1000 1024\times 1024, N_{\rm iter}=1000 1024×1024,Niter=1000)21.998647.691625.6484
FFT( 1024 × 1024 , N i t e r = 1000 1024\times 1024, N_{\rm iter}=1000 1024×1024,Niter=1000)1.961439.682939.9219
FFT( 512 × 512 , N i t e r = 1000 512\times 512, N_{\rm iter}=1000 512×512,Niter=1000)0.87799.44117.2179
FFT( 1024 × 128 , N i t e r = 1000 1024\times 128, N_{\rm iter}=1000 1024×128,Niter=1000)0.47344.24332.6365
FFT( 128 × 1024 , N i t e r = 1000 128\times 1024, N_{\rm iter}=1000 128×1024,Niter=1000)0.80794.17813.1636
FFT( 512 × 128 , N i t e r = 1000 512\times 128, N_{\rm iter}=1000 512×128,Niter=1000)0.25152.32161.3724
FFT( 128 × 512 , N i t e r = 1000 128\times 512, N_{\rm iter}=1000 128×512,Niter=1000)0.43832.32341.6585

运行效率平稳性分析

上一小节评估了不同语言的平均运行性能,下面看下单次运行效率.

Windows下的硬件环境:

  • CPU: Intel m3-6Y30@0.90GHz 1.51GHz
  • RAM: 4GB

Ubuntu下的硬件环境:

  • CPU: Intel E5-2696 v3 @ 2.30GHz × 36
  • RAM: 64GB

实验代码

FFT


from time import time
import numpy as np
from numpy.fft import fft


M, N = 2048, 2048
Niter = 300
x = np.random.rand(M, N) + 1j * np.random.rand(M, N)

tstart = time()
for n in range(Niter):
    t1 = time()
    y = fft(fft(x, axis=0), axis=1)
    t2 = time()
    print('---Iter: %d, time: %.4f ms' % (n, (t2 - t1) * 1000))

tend = time()
print('---Total time: %.4f s' % (tend - tstart))






M = 2048; N = 2048;
Niter = 300;
x = rand(M, N) + 1j * rand(M, N);

tstart = tic;
for n = 1:Niter
    t1 = tic;
    y = fft(fft(x, [], 1), [], 2);
    t2 = toc(t1);
    fprintf('---Iter: %d, time: %.4f ms\n', n, t2 * 1000)
end
tend = toc(tstart);
fprintf('---Total time: %.4f s\n', tend)

using FFTW
using Printf

FFTW.set_provider!("mkl")
FFTW.set_num_threads(18)

M, N = 2048, 2048
Niter = 300
x = rand(M, N) + im * rand(M, N)

tstart = time()
for n = 1:Niter
    t1 = time()
    y = fft(fft(x, 1), 2)
    t2 = time()
    @printf("---Iter: %d, time: %.4f ms\n", n, (t2 - t1)*1000)
end
tend = time()
@printf("---Total time: %.4f s\n", tend - tstart)

加噪

from time import time 
import numpy as np

f = 100
Fs = 800
Ts = 50.
Ns = int(Fs * Ts)
Nsnr = 61
SNRs = np.linspace(-30., 30., Nsnr)
Nk = 300

t = np.linspace(-Ts / 2., Ts / 2., Ns)
x = np.sin(2. * np.pi * f * t)

def noising(x, SNR):
    linearSNR = 10**(SNR / 10.)
    n = np.random.randn(*x.shape)
    Es = np.sum(x**2)
    En = np.sum(n**2)
    α = np.sqrt(Es / linearSNR / En)
    noise = α * n
    y = x + noise
    return y, noise


def calsnr(y, n):
    snrv = np.sum(y**2) / np.sum(n**2)
    return 10 * np.log10(snrv)


tstart = time()
for k in range(Nk):
    t1 = time()
    for SNR in SNRs:
        y, n = noising(x, SNR)
        snrv = calsnr(y, n)

    t2 = time()
    print('---Iter: %d, snr: %.2f, time: %.4f ms' % (k, snrv, (t2 -t1) * 1000))

tend = time()
print('---Total time: %.4f s' % (tend - tstart))




f = 100;
Fs = 800;
Ts = 50.;
Ns = uint32(Fs*Ts);
Nsnr = 61;
SNRs = linspace(-30., 30., Nsnr);
Nk = 300;

t = linspace(-Ts / 2., Ts / 2., Ns);
x = sin(2. * pi * f * t);

global snrv;
tstart = tic;
for k = 1:Nk
    t1 = tic;
    for i =1:Nsnr
        [y, n] = noising(x, SNRs(i));
        snrv = calsnr(y, n);
    end
    t2 = toc(t1);
    fprintf('---Iter: %d, snr: %.2f, time: %.4f ms\n', k, snrv, t2 * 1000);
end
tend = toc(tstart);
fprintf('---Total time: %.4f s\n', tend);

function [y, noise] = noising(x, SNR)
    linearSNR = 10^(SNR / 10.);
    n = randn(size(x));
    Es = sum(x.^2);
    En = sum(n.^2);
    alpha = sqrt(Es / linearSNR / En);
    noise = alpha * n;
    y = x + noise;
end

function [snrv] = calsnr(y, n)
    snrv = sum(y.^2) / sum(n.^2);
    snrv = 10 * log10(snrv);
end

using Printf


f = 100
Fs = 800
Ts = 50.
Ns = Int(Fs * Ts)
Nsnr = 61
SNRs = LinRange(-30., 30., Nsnr)
Nk = 300

t = LinRange(-Ts / 2., Ts / 2., Ns)
x = sin.(2. * pi * f * t)

function noising(x, SNR)
    linearSNR = 10^(SNR / 10.)
    n = randn(size(x))
    Es = sum(x.^2)
    En = sum(n.^2)
    α = sqrt(Es / linearSNR / En)
    noise = α * n
    y = x + noise
    return y, noise
end

function calsnr(y, n)
    snrv = sum(y.^2) / sum(n.^2)
    return 10 * log10(snrv)
end

tstart = time()
for k =1:Nk
    t1 = time()
    for SNR in SNRs
        y, n = noising(x, SNR)
        global snrv = calsnr(y, n)
    end
    t2 = time()
    @printf("---Iter: %d, snr: %.2f, time: %.4f ms\n", k, snrv, (t2- t1)*1000)
end
tend = time()
@printf("---Total time: %.4f s\n", tend - tstart)
    

实验结果

分别运行上述程序3次,将每次输出时间信息保存到log文件,如windows_fft_python_1.log, ubuntu_noise_julia_3.log, 使用下述代码绘制散点图. Julia和Python通过vscode运行.

import numpy as np
import pyaibox as pb
import matplotlib.pyplot as plt

os = 'windows'
os = 'ubuntu'
nshots = 300
nrow, ncol = 1, 3
plt.figure()
iters = np.linspace(1, nshots, nshots)
for n in range(1, nrow*ncol+1):
    tpy = pb.readnum('./%s_noise_python_%d.log' % (os, n), 'Iter', 'time: ', float, nshots)
    tma = pb.readnum('./%s_noise_matlab_%d.log' % (os, n), 'Iter', 'time: ', float, nshots)
    tju = pb.readnum('./%s_noise_julia_%d.log' % (os, n), 'Iter', 'time: ', float, nshots)

    plt.subplot(nrow, ncol, n)
    plt.grid()
    plt.scatter(iters, tpy)
    plt.scatter(iters, tma)
    plt.scatter(iters, tju)
    plt.legend(['Python', 'Matlab', 'Julia'])
    plt.title(n)
plt.show()

nshots = 300
nrow, ncol = 1, 3
plt.figure()
iters = np.linspace(1, nshots, nshots)
for n in range(1, nrow*ncol+1):
    tpy = pb.readnum('./%s_fft_python_%d.log' % (os, n), 'Iter', 'time: ', float, nshots)
    tma = pb.readnum('./%s_fft_matlab_%d.log' % (os, n), 'Iter', 'time: ', float, nshots)
    tju = pb.readnum('./%s_fft_julia_%d.log' % (os, n), 'Iter', 'time: ', float, nshots)

    plt.subplot(nrow, ncol, n)
    plt.grid()
    plt.scatter(iters, tpy)
    plt.scatter(iters, tma)
    plt.scatter(iters, tju)
    plt.legend(['Python', 'Matlab', 'Julia'])
    plt.title(n)
plt.show()

Windows 10

FFT 结果(纵轴:时间(ms), 横轴:迭代次数)
在这里插入图片描述

加噪声结果(纵轴:时间(ms), 横轴:迭代次数)

在这里插入图片描述

Ubuntu 16.04 LTS

FFT 结果(纵轴:时间(ms), 横轴:迭代次数)
在这里插入图片描述

加噪声结果(纵轴:时间(ms), 横轴:迭代次数)
在这里插入图片描述

其它资料

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐