Перейти к содержанию

Последнее обновление:2026-10-12

Параллельный STL в C++17

1. Степень поддержки различными компиляторами

Поддержка библиотеки параллельных алгоритмов различными компиляторами следующая:

https://en.cppreference.com/w/cpp/compiler_support/17#C.2B.2B17_library_features

Видно, что поддержка появилась после gcc9; clang пока поддерживает её не полностью — я сам проверил локально, и она действительно не работает.

fea

В число поддерживаемых алгоритмов входят:

all std

https://en.cppreference.com/w/cpp/experimental/parallelism

2. Требования библиотеки параллельных алгоритмов

После gcc9 уже можно использовать библиотеку параллельных алгоритмов; взглянем на документацию gcc-9 ниже.

https://gcc.gnu.org/gcc-9/changes.html

Там упоминается очень важная информация: требуется поддержка tbb.

tbb req

TBB — это библиотека C++ для параллельного программирования, разработанная компанией Intel. TBB призвана упростить разработку параллельного ПО для многоядерных процессоров, предоставляя набор абстракций и моделей, которые позволяют программистам легче реализовывать параллельные алгоритмы.

1.Предпосылка использования библиотеки параллельных алгоритмов в C++17 — установленный tbb; а что будет, если tbb не установить?

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

2.Как установить TBB?

Один вариант — официальный tbb, называется oneTBB.

https://github.com/oneapi-src/oneTBB

Другой — tbb, написанный другим человеком, называется tbb.

https://github.com/wjakob/tbb

Разница в том, что добавлена система сборки на основе CMake.

Сейчас официальный вариант тоже поддерживает cmake, поэтому рекомендую использовать официальный.

Компиляция тоже очень простая:

mkdir build && cmake ..
make -j8
make install

3. Как использовать

Что изменилось по сравнению с традиционным использованием STL?

1. Уровень интерфейсов

На самом деле всё довольно просто: например, sort раньше был таким:

std::sort(begin, end, comp);
Теперь стал таким:

std::sort(exe_policy, begin, end, comp);
Нужно лишь добавить политику выполнения (execution policy) — есть три варианта:

  1. std::execution::seq (последовательное выполнение):
  2. Это политика выполнения по умолчанию: если вы явно не указали политику, алгоритм будет выполняться последовательно.
  3. Алгоритм обрабатывает элементы строго по порядку, без параллельной обработки.
  4. std::execution::par (параллельное выполнение):
  5. Эта политика выполнения включает параллельность. Алгоритм пытается обрабатывать элементы параллельно, максимально задействуя многоядерный процессор.
  6. std::execution::par_unseq (параллельное и векторизованное выполнение):
  7. Эта политика позволяет алгоритму параллельно выполнять векторизацию (vectorization), то есть использовать набор инструкций SIMD (Single Instruction, Multiple Data) для параллельных векторных операций.
  8. В отличие от std::execution::par, par_unseq наряду с параллельной обработкой допускает и векторизацию, что позволяет полнее использовать возможности параллельности и векторизации оборудования.

2. Уровень заголовочных файлов

Обязательно подключить:

#include <algorithm>
#include <execution>
Если есть операции с tbb, можно подключить заголовочные файлы tbb, например: для задания числа потоков.

3. Уровень компиляции

При компиляции нужно указать информацию для линковки, например:

g++ -O3 -std=c++17 -Wall -Wextra -pedantic -I/usr/local/include/tbb -L /usr/local/lib/ -o main.out main.cc -ltbb

4. Тест производительности

В последнее время я занимаюсь работой, связанной с sort, и захотел сравнить производительность merge и sort, поэтому написал benchmark со следующей логикой:

  • последовательный sort vs параллельный sort (политика par)

  • последовательный merge vs параллельный merge (политика par)

Диапазон данных:

BENCHMARK(BM_ParallelSort)->Arg(16384)->Arg(16384000)->Arg(163840000);  
В приведённых ниже результатах тестов используется политика планирования потоков tbb по умолчанию.

Группа сравнения 1: параллельный Sort/последовательный Sort — подробные данные и коэффициент ускорения

sort parallel

sort parallel sp

Группа сравнения 2: параллельный Merge/последовательный Merge — подробные данные и коэффициент ускорения

merge parallel

merge parallel sp

Документация tbb:

https://oneapi-src.github.io/oneTBB/index.html

Если нужно задать число потоков, можно сделать так:

#include <tbb/tbb.h>

tbb::task_scheduler_init init(16);

Похожие темы

Комментарии