下面的代码片段是来自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]
另外请注意,variablescomp , dir和mol都是线程的局部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]之间的所有竞态条件都会引起问题。
更新 :根据下面的评论,这似乎并不是这样。
总结以上是内存溢出为你收集整理的为什么这个代码不是确定性的?全部内容,希望文章能够帮你解决为什么这个代码不是确定性的?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)