Следующий фрагмент кода из 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));
Проблема в том, что он не является детерминированным набарьер в конце, то есть, если вы выполняете этот код два раза с одними и теми же входами, это дает разные ответы.Другими словами, если порядок блокировки мьютексов изменяется, результаты будут другими.
И да, я подтвердил это, отметив страницы памяти.Также я могу заверить вас, что изменение происходит в памяти VAR (на что указывает temp_p ).
Я хочу знать, почему?Поскольку, очевидно, все потоки помещают свои собственные значения (PFORCES [ ProcID ] ...) в сумму temp_p , и в конце, то есть на барьере, результаты должныбыть одинаковыми, независимо от того, в каком порядке потоки приобрели блокировки.
[EDITED]
Также обратите внимание, что переменные comp , dir и моль являются локальными переменнымипоток и, следовательно, не разделяется.