微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么这个代码不是确定性的?

下面的代码片段是来自SPLASH 2的 water-nsq基准testing代码

if (comp_last > NMOL1) { for (mol = StartMol[ProcID]; mol < NMOL; moL++) { pthread_mutex_lock(&gl->MolLock[mol % MAXLCKS]); for ( dir = XDIR; dir <= ZDIR; dir++) { temp_p = VAR[mol].F[DEST][dir]; temp_p[H1] += PFORCES[ProcID][mol][dir][H1]; temp_p[O] += PFORCES[ProcID][mol][dir][O]; temp_p[H2] += PFORCES[ProcID][mol][dir][H2]; } pthread_mutex_unlock(&gl->MolLock[mol % MAXLCKS]); } comp = comp_last % NMOL; for (mol = 0; ((mol <= comp) && (mol < StartMol[ProcID])); moL++) { pthread_mutex_lock(&gl->MolLock[mol % MAXLCKS]); for ( dir = XDIR; dir <= ZDIR; dir++) { temp_p = VAR[mol].F[DEST][dir]; temp_p[H1] += PFORCES[ProcID][mol][dir][H1]; temp_p[O] += PFORCES[ProcID][mol][dir][O]; temp_p[H2] += PFORCES[ProcID][mol][dir][H2]; } pthread_mutex_unlock(&gl->MolLock[mol % MAXLCKS]); } } else { for (mol = StartMol[ProcID]; mol <= comp_last; moL++) { pthread_mutex_lock(&gl->MolLock[mol % MAXLCKS]); for ( dir = XDIR; dir <= ZDIR; dir++) { temp_p = VAR[mol].F[DEST][dir]; temp_p[H1] += PFORCES[ProcID][mol][dir][H1]; temp_p[O] += PFORCES[ProcID][mol][dir][O]; temp_p[H2] += PFORCES[ProcID][mol][dir][H2]; } pthread_mutex_unlock(&gl->MolLock[mol % MAXLCKS]); } } pthread_barrier_wait(&(gl->start));

问题在于最后的屏障并不是确定性的,也就是说,如果你使用相同的input执行这个代码两次,它会给出不同的答案。 换句话说,如果互斥锁的locking顺序改变了,结果是不同的。

是的,我通过logging页面来validation这一点。 另外我可以向你保证,变化发生在VAR (由temp_p指向 )内存中。

我想知道为什么? 因为显然,所有的线程都将自己的值(PFORCES [ ProcID ] …)与temp_p的总和相加,并且在最后,即在屏障上,结果应该是相同的,不pipe线程获得锁。

从C程序调用GCC时,抑制GCC错误输出

debuggingWindows窗体应用程序C#添加一个手表

在隐藏的应用程序启动时移除旋转球

X64机器上的x86 LARGEADDRESSAWARE程序的内核模式内存大小?

分离的pthread导致内存泄漏

[EDITED]

另外请注意,variablescompdirmol都是线程的局部variables,因此不能共享。

使用POLICY_CREATE_ACCOUNT访问掩码的LsaOpenPolicy,LsaAddAccountRights

C ++套接字窗口

支持全局数据的插件DLL的多个实例

你怎么能平行mmap来更快地读取文件

将string转换为cpp中的_T

第二次尝试。

我无法检查,但我认为在temp_p[H1] += PFORCES[ProcID][mol][dir][H1]; 你正在添加双打或浮动。

对于浮点类型,添加顺序很重要! 浮点加法不关联 !

不同的线程顺序意味着不同的添加顺序。 因此,预期结果的变化。

有关解释,请参见http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems 。

我注意到你不显示循环变量的声明,如mol和dir 。

难道是线程之间意外共享的吗?

如果是这样的话,例如一个线程的moL++和其他线程的[mol % MAXLCKS]之间的所有竞态条件都会引起问题。

更新 :根据下面的评论,这似乎并不是这样。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐