Ответ 1
На сегодняшний день большинство этих вопросов не могут быть удовлетворены стандартом. Однако ваш вопрос, как я понимаю, смешивает две концепции:
С1. Ограничения на параллельные алгоритмы
С2. Выполнение алгоритмов
Все параллельные STL файлы C++ имеют значение C1: он устанавливает ограничения на то, как команды и/или потоки могут чередоваться/трансформироваться в параллельном вычислении. С другой стороны, C2 - это стандартизация, ключевое слово - executor
(подробнее об этом позже).
Для C1 существует 3 стандартных политики (в std::execution::seq
par_unseq
std::execution::seq
, par
и par_unseq
), которые соответствуют каждой комбинации параллелизма задач и команд. Например, при выполнении целочисленного накопления можно использовать par_unseq
, так как порядок не важен. Однако, для поплавочной арифметики, где сложение не ассоциативно, лучше подходят бы seq
, чтобы, по крайней мере, получить детерминированный результат. Короче: политики устанавливают ограничения на параллельные вычисления, и эти ограничения могут потенциально использоваться интеллектуальным компилятором.
С другой стороны, как только у вас есть параллельный алгоритм и его ограничения (и, возможно, после некоторой оптимизации/преобразования), executor
найдет способ его выполнить. Существуют исполнители по умолчанию (например, для процессора), или вы можете создать свою собственную, тогда можно настроить все, что касается количества потоков, рабочей нагрузки, блока обработки и т.д.....
На сегодняшний день C1 находится в стандарте, но не C2, поэтому, если вы используете C1 с совместимым компилятором, вы не сможете указать, какой профиль выполнения вы хотите, и реализация библиотеки решит для вас (возможно, через расширения).
Итак, чтобы ответить на ваши вопросы:
(Что касается ваших первых 5 вопросов) По определению, параллельная библиотека STL C++ 17 не определяет какие-либо вычисления, просто зависимость данных, чтобы допускать возможные преобразования потока данных. На все эти вопросы будет ответить (надеюсь) executor
, вы можете увидеть текущее предложение здесь. Это будет выглядеть примерно так:
executor = get_executor();
sort( std::execution::par.on(executor), vec.begin(), vec.end());
Хотя некоторые из ваших вопросов уже определены в этом предложении, я не уверен в обсуждении их здесь... но я призываю вас прочитать его и придумать свой собственный ответ;)
(Для 6-го) Существует множество библиотек, которые уже реализуют подобные концепции (executor
C++ был вдохновлен некоторыми из них действительно), AFAIK: hpx, Thrust или Boost.Compute. Я не знаю, как реализованы последние два, но для hpx они используют легкие потоки, и вы можете настроить профиль выполнения. Кроме того, ожидаемый (еще не стандартизованный) синтаксис кода выше для C++ 17 по существу тот же, что и в (сильно вдохновлен) hpx.
Рекомендации:
- C++ 17 Параллельные алгоритмы и Beyond by Bryce Adelstein lelbach
- Будущее ISO C++ Неоднородные вычисления Майкла Вонга
- Основные исполнители C++ для включения гетерогенных вычислений в завтра C++ сегодня Майклом Вонгом
- Исполнители для C++ - длинная история Детлефа Вольмана