- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个函数 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/
我有以下用于并行归约的简单 Cython 函数: # cython: boundscheck = False # cython: initializedcheck = False # cython:
我正在尝试为每个 thead 分配一个单独的数组。但是,当我尝试为其分配值时,出现错误:错误:从“int”到“int*”的无效转换 [-fpermissive]这是代码: cdef void test
我正在从这里测试 prange 示例: http://numba.pydata.org/numba-doc/0.11/prange.html 我有 numba 版本 0.11.1 不幸的是,它给了我这
我刚刚写了一个简单的程序来测试 cython 的 prange 是如何执行的,下面是代码: from cython.parallel import prange import numpy as np
我正在尝试使用 prange 来处理多个字符串。由于无法使用 python 列表执行此操作,因此我使用 numpy 数组。 对于 float 数组,此函数可以工作: from cython.paral
Cython 启动器在这里。我正在尝试通过使用多个线程来加速计算某个成对统计数据(在几个 bin 中)。特别是,我正在使用来自 cython.parallel 的 prange,它在内部使用 open
我在这样的列表上使用 prange 进行迭代: from cython.parallel import prange, threadid cdef int tid cdef CythonElemen
使用 prange 与 range 进行比较时,更新 prange 循环中的列表会给出错误的结果。 from numba import jit, prange import numpy as np @
我正在尝试使用 Cython 的 prange 提高某些度量计算的性能。这是我的代码: def shausdorff(float64_t[:,::1] XA not None, float64_t[:
我有一个大的 prange 循环,可以在这里高效地执行一些过程。我想跟踪其中一个何时找到更好的结果。但是,似乎在 prange 循环内写入变量会创建一个新的私有(private)变量,因此无法以这种方
我正在尝试用 cython 重写一个使用 openmp 的 fortran 子例程。我发现在 cython 中重写 fortran 子例程本身没有困难。非 openmp 版本工作正常。但是,我不确定如
我尝试按如下方式并行化,紧随documented example : @numba.jit(nopython=True) def foo(uIdx, grids): return uIdx @
我正在使用 Cython 版本 0.27.3 为一个简单的素数测试模块编译以下源代码,该模块包含同一算法的 python 和 cython 实现。当我将 threads 参数设置为不同的值时,尽管 G
在另一个 Q+A ( Can I perform dynamic cumsum of rows in pandas? ) 中,我对使用 prange 的正确性发表了评论。关于此代码(this answ
我正在实现一种具有特定结构的顺序算法(卡尔曼滤波器),其中可以并行完成大量内部循环。我需要从这个函数中获得尽可能多的性能。目前,它在我的机器上运行大约 600 毫秒,具有代表性数据输入(n,p = 1
总是出现“pyeval_savethread: null tstate”错误 我尝试使用 cython 通过 prange 进行一些并行计算。但是我发现当我使用返回指针的函数时,我会得到上面的错误。我
在用 numba 并行化 3 个封装的 for 循环的实验中,我意识到幼稚的方法实际上并不能提高性能。以下代码产生以下时间(以秒为单位): 0.154625177383 # no numba 0.4
在两种情况下考虑优化的 cython 代码: for j in xrange(8): for x in xrange(1, 600): tmp[j] =
我有一个函数 foo,它将指向内存的指针作为参数,并写入和读取该内存: cdef void foo (double *data): data[some_index_int] = some_val
我是一名优秀的程序员,十分优秀!