Когда это возможно, вы, вероятно, захотите распараллелить внешний цикл. Самый простой способ сделать это в OpenMP - это сделать:
#pragma omp parallel for
for (long i = 0; i < n; i++) {
float sum = 0.0f;
for (long j = 0; j < m; j++) {
sum += data[i*m + j];
}
if (sum > threshold) {
#pragma omp critical
result_row_ind.push_back(i);
}
}
std::sort(result_row_ind.begin(),
result_row_ind.end());
Это работает, и, вероятно, намного быстрее, чем распараллеливание внутреннего цикла (запуск параллельной области стоит дорого), но он использует критическую секцию для блокировки для предотвращения гонок. Эту гонку также можно избежать, используя определяемое пользователем сокращение по векторам с сокращением в этом цикле, если число потоков очень велико, а количество совпадающих результатов очень мало, это может быть медленнее, но в противном случае это, вероятно, заметно быстрее , Это не совсем верно, тип вектора неполный, поскольку его нет в списке, но он должен быть довольно близок:
#pragma omp declare \
reduction(CatVec: std::vector<T>: \
omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) \
initializer(omp_priv=std::vector<T>())
#pragma omp parallel for reduction(CatVec: result_row_ind)
for (long i = 0; i < n; i++) {
float sum = 0.0f;
for (long j = 0; j < m; j++) {
sum += data[i*m + j];
}
if (sum > threshold) {
result_row_ind.push_back(i);
}
}
std::sort(result_row_ind.begin(),
result_row_ind.end());