Извините, я только начал изучать OpenMP, поэтому я немного растерялся.Я анализирую моё моделирование молекулярной динамики и в одной части кода пытаюсь найти ближайшее расстояние между молекулами воды (или ионами) и белком.Это очень трудоемкая часть, потому что у меня около 500000 атомов и около 25000 кадров.Для одного процессора это занимает 1 неделю (для набора вычислений не только расстояние).
Я изменил эту часть кода на параллельную с помощью OpenMP, и это действительно быстро, но с небольшой ошибкой;90% результатов (расстояния) верны, а 10% неверны, по сравнению с кодом одного процессора.Это часть моего кода, которая вычисляет ближайшее расстояние:
...
for (i=0; i< number of frames(25000) )
...
// XP,YP,ZP protein coordinates; malloc allocation in the code
// XI,YI,ZI Sodium molecule coordinates; malloc allocation
// LX,LY,LZ the dimension of simulation box, malloc allocation
// dimI defined as a temporary closest distance, filled with very large constant,
// malloc allocation
// NSOD number of Sodium molecules
// rhos keeping the closest distance for each Sodium for each frame.
…
...int l=0,kk=0;
#pragma omp parallel for shared(XI,YI,ZI,XP,YP,ZP,LX,LY,LZ,qq,dimI,distI,rhos,xmin,ymin,zmin,i) private(kk,l)
for (l=0; l < NSOD; l++){
// this part relocates every thing inside a box with dimension LX*LY*LZ. xmin, ymin and zmin are the boundaries of the box.
if (XI[l]!=0.0 || YI[l]!=0.0 || ZI[l]!=0.0){
if (XI[l] < xmin) XI[l] += ceil((xmin - XI[l])/LX[i-1]) * LX[i-1];
if (XI[l] > xmax) XI[l] -= ceil((XI[l] - xmax)/LX[i-1]) * LX[i-1];
if (YI[l] < ymin) YI[l] += ceil((ymin - YI[l])/LY[i-1]) * LY[i-1];
if (YI[l] > ymax) YI[l] -= ceil((YI[l] - ymax)/LY[i-1]) * LY[i-1];
if (ZI[l] < zmin) ZI[l] += ceil((zmin - ZI[l])/LZ[i-1]) * LZ[i-1];
if (ZI[l] > zmax) ZI[l] -= ceil((ZI[l] - zmax)/LZ[i-1]) * LZ[i-1];
}
for (kk=0; kk<NP; kk++){
if ( ( XP[kk]!=0. || YP[kk]!=0. || ZP[kk]!=0. ) ){
distI[l] = sqrt((XI[l]-XP[kk])*(XI[l]-XP[kk]) + (YI[l]-YP[kk])*(YI[l]-YP[kk]) + (ZI[l]-ZP[kk])*(ZI[l]-ZP[kk]) );
if (distI[l] < dimI[l] ) {
dimI[l] = distI[l];
}
}
}
distI[l] = dimI[l];
rhos[qq][l] = dimI[l];
} #pragma omp барьер ...
Не могли бы вы сказать, что не так с моим кодом после распараллеливания?Почему только в некоторых случаях это дает неправильный ответ, а не во всех случаях?Я высоко ценю ваши комментарии и рекомендации.Я использую GCC на Linux.Большое спасибо,
Приветствия, Араш