parallel-processing - 在 Cython 并行化期间如何附加到列表中?
问题描述
我必须将一个变量共享到 Cython 并行上下文中。
我想做这样的事情:
from cython.parallel import prange, parallel
cdef list factorize(cdef int n, cdef int limit):
cdef list factors
cdef int p
factors = []
with cython.nogil, parallel():
for p in prange(3, limit, 2):
if p * p > n: break
if n % p == 0:
factors.append(p)
n = n // p
if n > 1: factors.append(n)
return factors
如何factors
在并行上下文中附加到列表变量中?而且,为什么n // p
没有gil我不能做手术呢?我可以用这种方式实现这个方法吗?
PS:这只是一个例子,但我在其他上下文中有相同的 for 循环,所以我想知道我是否可以并行化这种类型的 for 循环,如果可能的话,我该怎么做?
解决方案
问:为什么没有我不能做手术?
n // p
GIL
出于某种原因,GIL 锁被用作重新[SERIAL]
执行任何并发代码执行的手段,这主要防止(通过锁定避免)任何两个线程在尝试修改公共对象时竞争和碰撞(n
- 是第一个这样的候选人,factors[]
出于同样的原因是第二个)
不锁定G
lobal ........意味着除了我之外没有人拥有(或不拥有)全球受人尊敬的 GIL
I
nterpereter ....是的,我们仍然生活在解释代码生态系统L
ock 中。 .............必须等待,直到确认我的 GIL 所有权,如果没有第一次拥有它,就无法继续修改对象
,
同时执行prange(3, limit, 2)
- 许多代码执行路径,将headbang 尝试分配到int n
(当然,重新关联,如果python pedantic)并且在尝试重新组织列表时遇到了同样的麻烦factors[]
,因为.append()
- 方法需要在内部进行一些内部手术“活”——病人。
如果不是 GIL-lock 麻醉,为了片刻不动,当 GIL-owner 且只有 GIL-owner 可以拿工具切割和重组患者的内部状态时,只有在手术完成,为了让factors[]
生活更进一步,在手术安全完成后释放GIL锁,如果许多外科医生切开内部静脉和其他任何东西,那么没有人会猜测内部状态会发生的折磨如此不愉快病人。
GIL 锁定只是防止了这场灾难性的大屠杀的发生,但代价是重新[SERIAL]
调整所有手术操作......
问:如何在并行上下文中附加到因素列表变量中?
最好的方法是附加到私人修改/专门用于编写的对象中,然后sum_reduce
在(现在主要是独立附加)并行部分完成工作之后“”它们。
推荐阅读
- odoo - 在 Odoo 13 中,我的记录规则不起作用。如果在全球范围内这个 domain_force 工作正常
- reactjs - monorepo 中的汇总打字稿别名问题
- vba - 提交错误的VBA IE自动化表单,表单未验证数据
- ruby - Ruby 为什么 rackup 在启动时会引发这个未定义的方法错误?
- tags - 如何在超级账本 indy 钱包中标记凭证
- firebase - 如何使用颤振将许多用户导入到 Firebase 身份验证
- java - 无权访问范围 - 亚马逊广告 API
- python - QGraphicsProxyWidget 搞乱了鼠标光标的变化
- ios - Carthage:使用 Forked LoopKit 时依赖图包含一个循环
- sql - 如何在 Postgresql (pgAdmin4) 中导入日期样式不一致的数据集?