Параллельный for_each с использованием openmp
-
20-09-2019 - |
Вопрос
Почему этот код не распараллеливает std::for_each(), когда он отлично работает с std::sort()?
Как мне это исправить?
g++ -fopenmp -D_GLIBCXX_PARALLEL=1 -o p p.cc && time ./p sort
GCC 4.3 в Linux.
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
void delay()
{
for(int c = 0; c < 1000000; c++) {
}
}
int lt(int a, int b)
{
delay();
return a < b;
}
void noop(int a)
{
delay();
}
int main(int argc, char **argv)
{
if (argc < 2) {
printf("%s <sort | for_each>\n", argv[0]);
return 1;
}
std::vector<int> foo(10000);
if (!strcmp(argv[1], "sort")) {
std::sort(foo.begin(), foo.end(), lt);
} else if (!strcmp(argv[1], "for_each")) {
std::for_each(foo.begin(), foo.end(), noop);
}
}
Решение
Просто компилирую с -D_GLIBCXX_PARALLEL
не обязательно распараллеливать все алгоритмы (см. здесь):
Пожалуйста, обратите внимание, что это не обязательно означает, что все в конечном итоге будет выполняться параллельно, скорее, эвристика и настройки, закодированные в параллельных версиях, будут использоваться для определения того, будут ли выполняться все, некоторые или ни один алгоритм с использованием параллельных вариантов.
Однако в Конфигурирование и настройка Глава может помочь вам принудительно выполнить распараллеливание.
Просто примечание к вашему "Эталону":std::sort
и std::for_each
не обязательно будет звонить delay()
столько же раз. std::for_each
вызывает метод задержки для N
времена, std::sort
называет это чем-то средним между N log(N)
и N^2
времена (см. ссылка).Таким образом, измерение времени выполнения дает вам лишь слабое представление о распараллеливании.