Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么这个代码不是确定性的?_C_Linux_Multithreading_Pthreads - Fatal编程技术网

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

C 为什么这个代码不是确定性的?,c,linux,multithreading,pthreads,C,Linux,Multithreading,Pthreads,下面的代码片段是来自water nsq的代码,来自SPLASH 2 if (comp_last > NMOL1) { for (mol = StartMol[ProcID]; mol < NMOL; mol++) { pthread_mutex_lock(&gl->MolLock[mol % MAXLCKS]); for ( dir = XDIR; dir <=

下面的代码片段是来自water nsq的代码,来自SPLASH 2

    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));
if(comp\u last>NMOL1)
{
对于(mol=StartMol[ProcID];molMolLock[mol%MAXLCKS]);
对于(dir=XDIR;dir-MolLock[mol%MAXLCKS]);
}
comp=comp_最后%NMOL;
对于(mol=0;((mol MolLock[mol%MAXLCKS]);
对于(dir=XDIR;dir-MolLock[mol%MAXLCKS]);
}
}
其他的
{
对于(mol=StartMol[ProcID];mol-MolLock[mol%MAXLCKS]);
对于(dir=XDIR;dir-MolLock[mol%MAXLCKS]);
} 
}
pthread_barrier_wait(&(gl->start));
问题在于,它最终在屏障处是不确定的,也就是说,如果您使用相同的输入执行此代码两次,它会给出不同的答案。换句话说,如果更改互斥锁的锁顺序,结果是不同的

是的,我已经通过记录内存页验证了这一点。我还可以向您保证,变化发生在VAR(由temp指向)内存中

我想知道为什么?因为显然,所有线程都将自己的值(PFORCES[ProcID])加在temp的和上,最后,也就是在屏障处,结果应该是相同的,无论线程获取锁的顺序如何

[已编辑]


另外,请注意变量compdirmol都是线程的局部变量,因此不共享。

我注意到您没有显示循环变量的声明,如
mol
dir

可能是线程之间意外共享了数据吗

如果是这样,例如一个线程的
mol++
和另一个线程的
[mol%MAXLCKS]
之间的所有类型的争用条件都会导致问题

更新:根据下面的评论,情况似乎并非如此。

第二次尝试

我无法检查它,但我假设在
temp_p[H1]+=PFORCES[ProcID][mol][dir][H1];
中添加了双精度或浮点

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

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


请参阅以获取一些解释。

发布完整的工作代码。这是在哪个处理器系列上运行的?并非所有处理器都具有相同的缓存一致性保证。您可能需要查看内存围栏。Nawaz,您可以从网站上获得这一代码。基准名称是water-nsq.spraff,它在x86上运行。我在单核和单核上都运行它d双核,但在这两种情况下,我得到了相同的行为。内存隔离应该是多核的问题,不是吗?在我看来。这段代码非常需要重构。我不知道这两种情况之间有什么不同。当你有那么多接近重复的代码时,会调用另一个函数。不,我可以向你确认mol和dir是lo线程的cal变量,不是共享的。@metallicprate好吧,没有显示完整的代码,我只能猜测。很有趣!是的temp是双精度的。有什么方法可以解决这个问题吗?很好的答案!我想这正是它不确定的原因。但非常令人惊讶的事实:)!解决什么?所使用的算法本质上是不确定的。如果这是一个问题,则算法的选择是不正确的。例如,您可以切换到定点数学,以确保加法顺序无关紧要。