小编hic*_*cup的帖子

Julia性能与Python + Numba LLVM/JIT编译代码相比

到目前为止我已经看过Julia的性能基准,例如http://julialang.org/,将Julia与纯Python或Python + NumPy进行比较.与NumPy不同,SciPy使用BLAS和LAPACK库,在这里我们获得了最佳的多线程SIMD实现.如果我们假设Julia和Python在调用BLAS和LAPACK函数时是相同的(在引擎盖下),当使用Numba或NumbaPro代码不调用BLAS或LAPACK函数时,Julia的性能与CPython相比如何?

我注意到的一件事是Julia使用LLVM v3.3,而Numba使用llvmlite,它建立在LLVM v3.5上.Julia的旧LLVM是否会阻止在较新的体系结构上实现最佳的SIMD实施,例如Intel Haswell(AVX2指令)?

我对意大利面条代码和小DSP循环的性能比较感兴趣,以处理非常大的向量.由于将数据移入和移出GPU设备内存的开销,后者由CPU为我更有效地处理GPU.我只对单个Intel Core-i7 CPU的性能感兴趣,因此集群性能对我来说并不重要.我特别感兴趣的是创建DSP功能的并行化实现的轻松和成功.

这个问题的第二部分是Numba与NumbaPro的比较(忽略了MKL BLAS).target="parallel"鉴于Numba装饰师的新nogil论点,NumbaPro 真的需要@jit吗?

python performance julia numba numba-pro

13
推荐指数
2
解决办法
3388
查看次数

如何使用 BLAS 函数将指针传递给子数组?

我正在使用 Julia v0.3.5,它附带 WinPython 3.4.2.5 build 4。我是 Julia 的新手。我正在测试 Julia 与使用 SciPy 的 BLAS 包装器进行 ddot() 相比有多快,ddot() 具有以下参数:x,y,n,offx,incx,offy,incy。Julia 的 OpenBLAS 库没有偏移参数,因此我试图找出如何在最大化速度的同时模拟它们。我多次传递 1GB 数组(向量)的 100MB 子数组,因此我不希望 Julia 创建每个子数组的副本,这会降低速度。Python 的 SciPy 函数需要几个小时才能执行,因此希望优化 Julia 的速度。我一直在阅读有关 Julia 0.4 如何提供数组视图来避免不必要的复制的内容,但我不清楚 Julia 0.3.5 如何处理这个问题。

到目前为止,我使用 REPL 得知 BLAS dot() 函数与 linalg/matmul.jl 中的方法冲突。因此,我学会了这样访问它:

import Base.LinAlg.BLAS
methods(Base.LinAlg.BLAS.dot)
Run Code Online (Sandbox Code Playgroud)

从方法显示中,我看到我可以传递指向 x 和 y 子数组的指针,从而避免复制。例如:

x = [1., 2., 3.]
y = [4., 5., 6.]
Base.LinAlg.BLAS.dot(2, pointer(x), 1, pointer(y), 1)
Run Code Online (Sandbox Code Playgroud)

但是,当我向指针添加整数偏移量(以访问子数组)时,REPL 崩溃。

如何在Base.LinAlg.BLAS.dot不减慢该子数组副本速度的情况下传递指向子数组或子数组的指针?还有什么我错过的吗?

pointers julia

5
推荐指数
1
解决办法
700
查看次数

如何获得多线程dot()函数?

当我在具有8个逻辑CPU内核的64位Windows 8.1 PC上的Julia v0.3.7的REPL中执行此操作时:

blas_set_num_threads(CPU_CORES)
const v=ones(Float64,100000)
@time for k=1:1000000;s=dot(v,v);end
Run Code Online (Sandbox Code Playgroud)

我在任务管理器或Process Explorer的CPU仪表中观察到只使用了12.5%的CPU(1个逻辑CPU核心).在Windows 7和Windows 8.1上,我也对Julia v0.3.5也有同样的看法.我也通过在命令行上启动"Julia -p 8"来观察相同的行为.在没有"-p 8"命令行选项的情况下返回运行Julia REPL,我尝试了这个测试:

blas_set_num_threads(CPU_CORES)
@time peakflops(10000)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,CPU仪表显示100%的CPU使用率.

既然dot()peakflops()都使用BLAS(在我的情况下是OpenBLAS),我希望两者都使用指定的线程数blas_set_num_threads().但是,只有后一种功能才能实现.dot()可能是在OpenBLAS中是由于一个bug 的行为?

我试图通过使用矩阵乘法函数来解决Julia的缺点.但是,我正在迭代dot()GB大小的2D数组的子向量上的操作,其中子向量使用连续的内存.矩阵乘法迫使我转置每个向量,从而创建一个副本.这在内循环中是昂贵的.因此,我的选择似乎要么学习如何使用Julia的并行处理命令/宏,要么回到Python(英特尔的MKL BLAS按预期运行ddot()).由于dot()在我尝试编写的例程中消耗99%CPU的功能,我希望OpenBLAS能在Julia中为我提供用户友好的最佳解决方案,而不必担心引擎盖下的所有并行处理复杂性.但也许它不是那么糟糕......

我可以使用一些创建多线程dot()函数.一些示例代码将是最好的帮助.当所有线程在同一台机器上运行时,是否需要使用SharedArray?如果是这样,从Array转换为SharedArray会创建副本吗?由于我的数组非常大,我不希望同时在内存中有两个副本.因为我的向量大约是100,000个,并且来自一个数组的向量以不可预测的顺序使用,对我来说最好的多线程解决方案是dot()函数,它将任务分配到可用的核心中,并对结果进行求和.每个核心.如何在Julia中像BLAS一样高效地完成这项工作?

我在这里看到Tim Holy的答案: BLAS诉Julia SharedArray对象的并行更新 然而,他的例子(我认为)dot()在一个核心上执行整个函数,并且它不回答我的其他问题.

编辑1:我尝试使用"-p 8"命令行选项运行Julia并dot()在上面替换上面的示例innersimd():http: //docs.julialang.org/en/release-0.3/manual/performance-tips/ 仍然只使用1个核心.我修改innersimd()为键入其参数::Array{Float64, 1}然后::SharedArray{Float64, 1},但这仍然使用1核心.:(

编辑2:我测试了Julia的矩阵乘法(BLAS'gemm!()函数):

blas_set_num_threads(CPU_CORES)
const A=ones(Float64,(4,100000))
const B=ones(Float64,(100000,4))
@time for k=1:100000;s=A*B;end
Run Code Online (Sandbox Code Playgroud)

即使Julia没有使用"-p"命令行选项,Julia也只使用了一个核心.

编辑3:这是Python的可比测试代码: …

multithreading julia

4
推荐指数
1
解决办法
1373
查看次数