我有这个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) 我需要概述一下在高性能数字代码中使用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) 通常我可以在使用 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)