python - 种族条件?- 多线程结果不同于单线程
问题描述
我正在研究一种并行 Cython 算法,该算法利用“prange”函数进行并行化。基本上,我有一个并行更新的 numpy 内存视图。我注意到由于值与单线程结果不同,因此存在竞争条件或正在发生的事情。有没有人有什么方向可以告诉我在哪里看?
我试图调整“prange”参数,但似乎并没有解决问题。我对 C 的理解相当有限,但我确实读过它,发现循环中的变量都是私有的,因为它们应该是私有的。
mp 和 mpi 是内存视图。
for diag in prange(minlag, profile_len, num_threads=n_jobs, nogil=True):
c = 0
for i in range(diag, diag + w):
c = c + ((ts[i] - mu[diag]) * (ts[i-diag] - mu[0]))
for offset in range(n - w - diag + 1):
c = c + df[offset] * dg[offset + diag] + df[offset + diag] * dg[offset]
c_cmp = c * sig[offset] * sig[offset + diag]
# update the distance profile and profile index
if c_cmp > mp[offset]:
if c_cmp > 1:
c_cmp = 1
mp[offset] = c_cmp
mpi[offset] = offset + diag
if c_cmp > mp[offset + diag]:
if c_cmp > 1:
c_cmp = 1
mp[offset + diag] = c_cmp
mpi[offset + diag] = offset
单线程和多线程的 mp 和 mpi 值应该相同。现在情况并非如此。
解决方案
for offset in range(n - w - diag + 1):
# ... some stuff ...
mp[offset] = c_cmp
mpi[offset] = offset + diag
# ... some stuff ...
mp[offset + diag] = c_cmp
mpi[offset + diag] = offset
对某个数字的一系列偏移量的分配mp
和mpi
运行0
(我们不知道,因为它是一个不完整的示例,但这并不特别重要)。这发生在每个线程中。
由于您的算法似乎可以在循环中更新和在同一循环中mp
使用mp
,因此对我来说似乎不是特别可并行化。(可以改为并行化内部 ( offset
) 循环,但我认为这会导致...[offset + diag]
线路出现问题。)
本质上,如果您将循环与索引并行化,diag
那么您应该在循环中更改的唯一内容是:
单个值作为“减少变量” (
+-*/
)diag
使用且仅diag
索引的数组。
其他事情有时是可能的,但您必须完全了解自己在做什么,并向自己证明多个线程不会写入相同的数据。
推荐阅读
- database - 客户端服务器连接
- c++ - 无法在同一行上获得输出,C++ 中的两个输出之间有空格
- r - 重新排序 geom_bar 中的条形图
- google-cloud-dataproc - Dataproc 作业详细信息未显示在网络控制台上
- angular - “AbstractControl”类型上不存在属性“控件”
- reactjs - 为什么在链接到我的组件后不调用 mapDispatchToProps?
- actions-on-google - Google 上的 DialogFlow 操作:dialogflow-helper-intents-nodejs 教程 - 自定义意图缺少查询模式
- javascript - 关联具有不同高度的单独元素以沿垂直中心线排列
- python - 将 A+"COMBINING ACUTE ACCENT" 转换为 Á
- java - 从 Java 读取文件 excel 版本 4