Убедитесь, что взаимодействия i,j
и j,i
, которые влияют на одни и те же данные, не вызывают гонок данных. Вы можете сделать это, тщательно настраивая распределение работы или используя omp critical
или omp atomic
конструкции, где это необходимо.
Кроме того, нет проблем с тем, чтобы заставить ваш код работать быстрее, просто используя конструкции omp parallel for
во внешнем цикле. Имейте в виду, что если количество процессорных блоков (ядер, многопоточных и т. Д.) Имеет ваш процессор, или если вы используете компьютер ccNUMA, было бы неплохо сделать некоторые дополнительные действия, поскольку масштабируемость вашего кода будет не так хорошо, как могло бы.
Самое простое улучшение - добавить collapse(2)
к вашему предложению omp for
. Это скажет OpenMP, что вы хотите распределить итерации обоих этих циклов.
#pragma omp parallel for collapse(2)
for(int i=0;i<agents.size();i++){
for(int j=0;j<agents.size();j++){
if(i==j) continue;
if(distance_between(i,j)<10){
//do a lot of calculations for interaction between i and j,
//and a bunch of changes to variables of the Agents stored in the list
}
}
}
Как только вы достигнете огромного количества частиц (или агентов, как вы их называете), было бы разумно отсортировать их все в соответствии с их положением. Это приведет к тому, что ваше условие if
внутри самого внутреннего цикла будет иметь более стабильное поведение, что позволит лучше прогнозировать ветви (см. , почему это быстрее для обработки отсортированного массива ).
Кроме того, вы можете полностью удалить ветвь, если разделите геометрическое пространство на ячейки. Это потому, что вы точно знаете, что несмежные сегменты находятся слишком далеко для успешного выполнения условия.
Подобные проблемы очень хорошо известны, и, как вы, возможно, уже знаете, они называются проблемами n-тела . Версия оптимизации корзины называется имитация Барнса-Хата , хотя вы можете обнаружить, что другие подходы работают намного быстрее (хотя их труднее распараллелить, но в большинстве случаев они все еще более эффективны), такие как Fast Multipole Метод , который более или менее состоит в сокращении числа вычислений путем решения обоих взаимодействий i,j
и j,i
за один шаг.