Сворачивание двух циклов for из трех в OpenMP

#loops #for-loop #openmp

#циклы #цикл for #openmp

Вопрос:

Я проверял чужой код OpenMP и увидел эти три вложенных цикла for, где сворачивались только (первые?) два из них:

 #pragma omp for collapse(2)
  for(int i=0;i<nxn;i  )
  for(int j=0;j<nyn;j  )
  for(int k=0;k<nzn;k  )
  {
    rhons[is][i][j][k]  = invVOL*moments[i][j][k][0];
    Jxs  [is][i][j][k]  = invVOL*moments[i][j][k][1];
    Jys  [is][i][j][k]  = invVOL*moments[i][j][k][2];
    Jzs  [is][i][j][k]  = invVOL*moments[i][j][k][3];
    pXXsn[is][i][j][k]  = invVOL*moments[i][j][k][4];
    pXYsn[is][i][j][k]  = invVOL*moments[i][j][k][5];
    pXZsn[is][i][j][k]  = invVOL*moments[i][j][k][6];
    pYYsn[is][i][j][k]  = invVOL*moments[i][j][k][7];
    pYZsn[is][i][j][k]  = invVOL*moments[i][j][k][8];
    pZZsn[is][i][j][k]  = invVOL*moments[i][j][k][9];
  }
  

Мой вопрос в том, возможно ли свернуть все три цикла? Я имею в виду, я пытаюсь понять логику разработчика (предполагается, что он очень опытный) — почему он этого не сделал?

Комментарии:

1. Причиной сворачивания внешних циклов является более равномерное распределение работы по потокам. Включение внутреннего цикла в collapse помешало бы векторизации, вероятно, предотвратив ее, если вы не установите simd и не используете подходящий компилятор.

2. Принятый ответ неверен!

3. Хорошо, на случай, если эти ответы остаются запутанными, collapse(2) объединяет 2 внешних цикла и оставляет внутренний цикл зависящим от настроек компилятора, таких как автоматическая векторизация. Вероятно, это хороший выбор.

Ответ №1:

Вы могли бы это сделать, но какую пользу это принесло бы?

Давайте предположим, что nxn * nyn это значительно больше OMP_NUM_THREADS . Таким образом, итерации цикла уже доступны для эффективного распараллеливания.

С другой стороны, внутренний цикл имеет высокую локальность данных. Хотя OpenMP, вероятно, сохранит это, может быть определенная оптимизация, заключающаяся в том, что последнее измерение массивов кратно строкам кэша, поэтому было бы неразумно разделять их между потоками. Как упоминалось tim18, возможное вмешательство в векторизацию внутреннего цикла может стать еще одной проблемой при сворачивании всех циклов.

Таким образом, в принципе, это не приносит никакой пользы, но потенциально может негативно сказаться на производительности при глупой реализации OpenMP.