相关疑难解决方法(0)

Cython中C++函数性能不佳

我有这个C++函数,我可以使用下面的代码从Python调用它.与运行纯C++相比,性能只有一半.有没有办法让他们的表现达到同一水平?我用-Ofast -march=native标志编译两个代码.我不明白我可以在哪里丢失50%,因为大部分时间都应该花在C++内核上.Cython是否制作了我可以避免的内存副本?

namespace diff
{
    void diff_cpp(double* __restrict__ at, const double* __restrict__ a, const double visc,
                  const double dxidxi, const double dyidyi, const double dzidzi,
                  const int itot, const int jtot, const int ktot)
    {
        const int ii = 1;
        const int jj = itot;
        const int kk = itot*jtot;

        for (int k=1; k<ktot-1; k++)
            for (int j=1; j<jtot-1; j++)
                for (int i=1; i<itot-1; i++)
                {
                    const int ijk = i + j*jj + k*kk;
                    at[ijk] += visc …
Run Code Online (Sandbox Code Playgroud)

c++ python numpy cython

8
推荐指数
1
解决办法
852
查看次数

从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
查看次数

使用 Cython 实现 Numba 的性能

通常我可以在使用 Cython 时匹配 Numba 的性能。然而,在这个例子中我没有这样做 - Numba 比我的 Cython 版本快大约 4 倍。

这里是 Cython 版本:

%%cython -c=-march=native -c=-O3
cimport numpy as np
import numpy as np
cimport cython

@cython.boundscheck(False)
@cython.wraparound(False)
def cy_where(double[::1] df):
    cdef int i
    cdef int n = len(df)
    cdef np.ndarray[dtype=double] output = np.empty(n, dtype=np.float64)
    for i in range(n):
        if df[i]>0.5:
            output[i] = 2.0*df[i]
        else:
            output[i] = df[i]
    return output 
Run Code Online (Sandbox Code Playgroud)

这是 Numba 版本:

import numba as nb
@nb.njit
def nb_where(df):
    n = len(df)
    output = np.empty(n, dtype=np.float64)
    for …
Run Code Online (Sandbox Code Playgroud)

python performance x86 cython numba

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

标签 统计

cython ×3

python ×3

c++ ×1

numba ×1

numpy ×1

performance ×1

x86 ×1