我使用prange来修改数组。我试图在cython编译器生成的HTML页面中尽量少使用黄色行:
cython function_prange.pyx -a但是,当提取数组的一部分来修改它时,我总是会生成这样的代码:
{
#ifdef WITH_THREAD
PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
#endif
#ifdef _OPENMP
#pragma omp flush(__pyx_parallel_exc_type)
#endif /* _OPENMP */
if (!__pyx_parallel_exc_type) {
__Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb);
__pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno;
__Pyx_GOTREF(__pyx_parallel_exc_type);
}
#ifdef WITH_THREAD
PyGILState_Release(__pyx_gilstate_save);
#endif
}是否有可能避免这些__Pyx_ErrFetchWithState / __Pyx_ErrRestoreWithState?这真的有关系吗?
下面是我使用的代码:
第一个函数,在function_nogil.pyx中的一个大小为一个的数组中,在矩阵的对角线上添加一个双对角。
import cython
@cython.boundscheck(False) # turn off bounds-checking for entire function
@cython.wraparound(False) # turn off negative index wrapping for entire function
cdef void add_diag(double [:,:,:] a, int a_len, int a_wid, double coeff) nogil:
cdef int x_max = a_len
cdef int x
for x in xrange(x_max):
a[0,x,x] = a[0,x,x] + coeff在function_nogil.pxd中的头
cdef void add_diag(double [:,:,:] a, int a_len, int a_wid, double coeff) nogilfunction_prange.pyx中使用prange的函数
@cython.boundscheck(False) # turn off bounds-checking for entire function
@cython.wraparound(False) # turn off negative index wrapping for entire function
def prange_loop_idx(double [:,:,:] a, int a_dim1, int a_dim2, int a_dim3, double coeff,int num_threads):
cdef int i = 0
with nogil,parallel(num_threads=num_threads):
for i in prange(a_dim1):
add_diag(a[i:i+1:,],a_dim2,a_dim3,coeff)发布于 2017-06-21 13:52:15
它并没有看上去那么糟糕。当您查看完整的C代码时,您会发现这只是一个错误处理代码,只有在错误条件下用goto跳到它才能执行。
(错误条件是它检查内存视图切片的构造是否正确--我认为这是使用片而不是单一索引的结果。将步骤设置为0会在这里触发一个错误)。
因此,您有一些额外的错误检查,这可能不是严格意义上的必要,但我认为最好还是不要插手(在我的PC上,这是这一行):
if (unlikely(__pyx_memoryview_slice_memviewslice(
&__pyx_t_4,
__pyx_v_a.shape[0], __pyx_v_a.strides[0], __pyx_v_a.suboffsets[0],
0,
0,
&__pyx_t_5,
__pyx_v_i,
(__pyx_v_i + 1),
0,
1,
1,
0,
1) < 0))
{
__PYX_ERR(0, 21, __pyx_L12_error)
}但是您担心的实际代码并不是在正常操作中调用的,因此几乎没有成本,您可以忽略。
我认为parallel和prange生成的代码可能非常复杂,因此生成的html文件在显示正确的位时并不是100%有用的,这就是为什么您看到它链接到了这一行,但是您没有看到我前面展示的错误检查代码。
https://stackoverflow.com/questions/44675920
复制相似问题