相关疑难解决方法(0)

为什么这个numba代码比numpy代码慢6倍?

是否有任何理由为什么以下代码在2s运行,

def euclidean_distance_square(x1, x2):
    return -2*np.dot(x1, x2.T) + np.expand_dims(np.sum(np.square(x1), axis=1), axis=1) + np.sum(np.square(x2), axis=1)
Run Code Online (Sandbox Code Playgroud)

而以下numba代码在12s运行?

@jit(nopython=True)
def euclidean_distance_square(x1, x2):
   return -2*np.dot(x1, x2.T) + np.expand_dims(np.sum(np.square(x1), axis=1), axis=1) + np.sum(np.square(x2), axis=1)
Run Code Online (Sandbox Code Playgroud)

我的x1是尺寸矩阵(1,512),x2是尺寸矩阵(3000000,512).Numba可以慢得多,这很奇怪.我用错了吗?

我真的需要加快速度,因为我需要运行这个功能300万次而且2s仍然太慢了.

我需要在CPU上运行它,因为你可以看到x2的维度是如此巨大,它无法加载到GPU(或至少我的GPU),没有足够的内存.

python numpy numba

14
推荐指数
3
解决办法
2463
查看次数

为什么numpy sum比+运算符慢10倍?

我注意到,非常紧张,np.sum比手写总和慢10倍.

带轴的np.sum:

p1 = np.random.rand(10000, 2)
def test(p1):
    return p1.sum(axis=1)
%timeit test(p1)
Run Code Online (Sandbox Code Playgroud)

每回路186μs±4.21μs(平均值±标准偏差,7次运行,每次1000次循环)

没有轴的np.sum:

p1 = np.random.rand(10000, 2)
def test(p1):
    return p1.sum()
%timeit test(p1)
Run Code Online (Sandbox Code Playgroud)

每回路17.9μs±236 ns(平均值±标准偏差,7次运行,每次10000次循环)

+:

p1 = np.random.rand(10000, 2)
def test(p1):
    return p1[:,0] + p1[:,1]
%timeit test(p1)
Run Code Online (Sandbox Code Playgroud)

每个环路15.8μs±328 ns(平均值±标准偏差,7次运行,每次100000次循环)

乘法:

p1 = np.random.rand(10000, 2)
def test(p1):
    return p1[:,0]*p1[:,1]
%timeit test(p1)
Run Code Online (Sandbox Code Playgroud)

每个环路15.7μs±701 ns(平均值±标准偏差,7次运行,每次10000次循环)

我没有看到任何理由.知道为什么吗?我的numpy版本是1.15.3.

编辑:10000000:

np.sum (with axis): 202 ms (5 x)
np.sum (without axis): 12 ms
+ : 46 ms (1 x)
* : 44.3 ms …
Run Code Online (Sandbox Code Playgroud)

python performance numpy

13
推荐指数
1
解决办法
753
查看次数

从Cython代码生成SIMD指令

我需要概述一下在高性能数字代码中使用Cython可以获得的性能.我感兴趣的一件事是找出优化的C编译器是否可以对Cython生成的代码进行矢量化.所以我决定编写以下小例子:

import numpy as np
cimport numpy as np
cimport cython

@cython.boundscheck(False)
@cython.wraparound(False)
cpdef int f(np.ndarray[int, ndim = 1] f):
    cdef int array_length =  f.shape[0]
    cdef int sum = 0
    cdef int k
    for k in range(array_length):
        sum += f[k]
    return sum
Run Code Online (Sandbox Code Playgroud)

我知道有Numpy函数可以完成这项工作,但我希望有一个简单的代码,以便了解Cython的可能性.事实证明,生成的代码:

from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules = cythonize("sum.pyx"))
Run Code Online (Sandbox Code Playgroud)

并呼吁:

python setup.py build_ext --inplace
Run Code Online (Sandbox Code Playgroud)

为循环生成一个看起来像这样的C代码:

for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2 += 1) {
  __pyx_v_sum = __pyx_v_sum + (*(int *)((char *) 
    __pyx_pybuffernd_f.rcbuffer->pybuffer.buf + …
Run Code Online (Sandbox Code Playgroud)

python cython

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

使用 Numba 更快地制作四个嵌套 for 循环

我对 Numba 的工作有点陌生,但我已经了解了它的要点。我想知道是否有更高级的技巧可以使四个嵌套for循环比我现在的速度更快。特别是,我需要计算以下积分:

在此输入图像描述

其中B是二维数组,S0和E是某些参数。我的代码如下:

import numpy as np
from numba import njit, double

def calc_gb_gauss_2d(b,s0,e,dx):
    n,m=b.shape
    norm = 1.0/(2*np.pi*s0**2)
    gb = np.zeros((n,m))
    for i in range(n):
        for j in range(m):
            for ii in range(n):
                for jj in range(m):
                    gb[i,j]+=np.exp(-(((i-ii)*dx)**2+((j-jj)*dx)**2)/(2.0*(s0*(1.0+e*b[i,j]))**2))
            gb[i,j]*=norm
    return gb

calc_gb_gauss_2d_nb = njit(double[:, :](double[:, :],double,double,double))(calc_gb_gauss_2d)
Run Code Online (Sandbox Code Playgroud)

对于大小为输入的数组,256x256计算速度为:

In [4]: a=random.random((256,256))

In [5]: %timeit calc_gb_gauss_2d_nb(a,0.1,1.0,0.5)
The slowest run took 8.46 times longer than the fastest. This could mean that an intermediate result is being cached.
1 …
Run Code Online (Sandbox Code Playgroud)

python iteration jit loops numba

3
推荐指数
1
解决办法
3451
查看次数

标签 统计

python ×4

numba ×2

numpy ×2

cython ×1

iteration ×1

jit ×1

loops ×1

performance ×1