Шаг моего кода, определяющий время, представляет собой тензорное сжатие следующей формы
#pragma omp parallel for schedule(dynamic)
for(int i = 0; i < no; ++i){
for(int j = 0; j < no; ++j){
X.middleCols(i*nv,nv) += Y.middleCols(j*nv,nv) * this->getIJMatrix(j,i);
}
}
, где X
и Y
- большие матрицы размерности (nx, no * nv) и функция getIJMatrix(j,i)
возвращает матрицу (nv * nv) для пары индексов ij
тензора четвертого ранга. Также no < nv << nx
. Распараллеливание здесь простое. Тем не менее, я могу использовать симметрию относительно i
и j
#pragma omp parallel for schedule(dynamic)
for(int i = 0; i < no; ++i){
for(int j = i; j < no; ++j){
auto ij = this->getIJMatrix(j,i);
X.middleCols(i*nv,nv) += Y.middleCols(j*nv,nv) * ij;
if(i!=j) X.middleCols(j*nv,nv) += Y.middleCols(i*nv,nv) * ij.transpose();
}
}
, оставив меня в состоянии гонки. Поскольку X
велико, использование сокращения здесь невозможно.
Если я правильно понимаю, нет никакого способа обойти каждый поток, ожидающий других во внутреннем l oop. Что для этого рекомендуется, чтобы сделать это как можно быстрее?
edit: исправлены очевидные ошибки