python - cython.parallel.prange 中的 cython 共享内存 - block

标签 python parallel-processing malloc cython python-multithreading

我有一个函数 foo,它将指向内存的指针作为参数,并写入和读取该内存:

cdef void foo (double *data):
   data[some_index_int] = some_value_double
   do_something_dependent_on (data)

我像这样分配给data:

cdef int N = some_int
cdef double *data = <double*> malloc (N * sizeof (double))

cdef int i
for i in cython.parallel.prange (N, nogil=True):
    foo (data)

readout (data)

我现在的问题是:不同的线程如何处理这个问题?我的猜测是 data 指向的内存将由所有线程共享,并在函数 foo 内“同时”读取或写入。这会弄乱所有结果,因为不能依赖先前设置的数据值(在 foo 内)?我的猜测是正确的还是在 cython 编译器中实现了一些神奇的安全带?

非常感谢您。

最佳答案

一个好方法是让主数组位于线程之外。然后你给每个线程一个指针,指向线程应该计算的主数组部分。

以下示例是矩阵乘法的实现(类似于二维数组的 dot),其中:

c = a*b

这里的并行是在 a 的行上实现的。检查指针是如何传递给 multiply 函数的,以便允许不同的线程共享相同的数组。

import numpy as np
cimport numpy as np
import cython
from cython.parallel import prange

ctypedef np.double_t cDOUBLE
DOUBLE = np.float64


def mydot(np.ndarray[cDOUBLE, ndim=2] a, np.ndarray[cDOUBLE, ndim=2] b):
    cdef np.ndarray[cDOUBLE, ndim=2] c
    cdef int i, M, N, K

    c = np.zeros((a.shape[0], b.shape[1]), dtype=DOUBLE)
    M = a.shape[0]
    N = a.shape[1]
    K = b.shape[1]

    for i in prange(M, nogil=True):
        multiply(&a[i,0], &b[0,0], &c[i,0], N, K)

    return c


@cython.wraparound(False)
@cython.boundscheck(False)
@cython.nonecheck(False)
cdef void multiply(double *a, double *b, double *c, int N, int K) nogil:
    cdef int j, k
    for j in range(N):
        for k in range(K):
            c[k] += a[j]*b[k+j*K]

要检查您是否可以使用此脚本:

import time

import numpy as np

import _stack

a = np.random.random((10000,500))
b = np.random.random((500,2000))

t = time.clock()
c = np.dot(a, b)
print('finished dot: {} s'.format(time.clock()-t))

t = time.clock()
c2 = _stack.mydot(a, b)
print('finished mydot: {} s'.format(time.clock()-t))

print 'Passed test:', np.allclose(c, c2)

它在我电脑上的什么位置:

finished dot: 0.601547366526 s
finished mydot: 2.834147917 s
Passed test: True

如果 a 的行数小于列数或 b 中的列数,则 mydot 会更糟,需要更好地检查在哪个维度上进行并行处理。

关于python - cython.parallel.prange 中的 cython 共享内存 - block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19002486/

相关文章:

parallel-processing - Common Lisp (SBCL) 是否具有高级并行功能?

c - 错误: difference between perror and fprintf

c - 在 C 中,我如何选择是返回结构还是指向结构的指针?

如果我有 "lost"最后剩余的指针,我可以访问动态分配的内存吗?

python - 来自 pandas 数据框的输入的 sklearn classification_report 产生 : "TypeError: not all arguments converted during string formatting"

c++ - openMP 新手,有什么建议可以将以下代码与 openMP 并行吗?

python - SimpleXmlRpcServer _sock.rcv 在数千次请求后卡住

c++ - 英特尔 MIC 上的英特尔 TBB 和 Cilk Plus 线程亲和性

python - 是否有一个 `np.repeat` 作用于现有数组?

python - 如何更新通过 "OneToOneField"扩展的用户模型