Давайте вернёмся к примеру с генерацией и с суммированием элементов матрицы. При этом у меня вот сейчас в Эклипсе находится вариант кода, с которого мы начинали. То есть вариант, в котором есть только однопоточная генерация и однопоточное суммирование; ну никакого другого суммирования мы не писали. У меня есть вот эта функция GenerateSingleThread однопоточная, но я её немножечко переписал. У нас здесь был обычный цикл for, который бежал вот по переменной result и для каждой строки матрицы он выполнял, он её заполнял. Я этот цикл for переписал на алгоритм for_each. Алгоритм for_each, по сути, делает то же самое. Он принимает два итератора — begin и end и λ, вернее, какую-то функцию (не обязательно λ). Эта функция вызывается для каждого элемента вот этой последовательности. Вот я написал λ-функцию, которая в параметре принимает вектор int, то есть очередную строку нашей матрицы, и делает то же самое, что и делала раньше. Она делает ей reserve и потом бежит слева направо и заполняет результатом ксора номера строки и номера столбца. Вот таким образом я переписал. Просто заменил цикл for на for_each. Просто алгоритм for_each существует в C++ достаточно давно, ещё, если я не ошибаюсь, со стандарта 1998 года. А цикл for (range-based-for) был добавлен в C++11 в 2011 году. До цикла range-based-for алгоритм for_each был достаточно актуален. Сейчас его область применения весьма сузилась. И смотрите: зачем я это сделал? Я это сделал для того, чтобы решить другим образом нашу исходную задачу — — распараллелить генерацию матрицы. Дело в том, что в стандарте C++17, который был утверждён в 2017 году, были введены параллельные версии стандартных алгоритмов. то есть мы берём какой-то стандартный алгоритм (в данном случае for_each) и мы можем достаточно просто его распараллелить. Вот смотрите: мы открываем документацию на алгоритм for_each и видим, что у него есть вот эта вот вторая версия, в которой в качестве первого параметра принимается некий ExecutionPolicy, то есть дальше он принимает ForwardIt, итератор first, итератор last и UnaryFunction — это функция, которую он выполняет для каждого элемента последовательности. Но первый параметр — это некая Policy. При этом чтобы понять, что такое Policy, мы переходим в блок Parameters, и здесь написано, что see execution policy for details. Нажимаем. И здесь описывается, что есть несколько вот этих политик исполнения — последовательная, параллельная и parallel_unsequenced_policy, то есть параллельная, не сохраняющая порядок. И тут приводятся разные примеры. И вот есть три константы глобальные — это seq, par и par_unseq. Это, собственно, константы, которые задают, какую политику исполнения алгоритма мы хотим использовать. При этом вот здесь вверху (тут достаточно мелко, я ещё увеличу), вот здесь написано, что эти политики объявлены в заголовочном файле execution. Поэтому чтобы нам получить параллельную версию алгоритма for_each, нам достаточно сделать простую вещь: подключить заголовочный файл execution и вот здесь в качестве первого параметра указать execution: par. Всё, вот этими двумя строчками мы распараллелили наш алгоритм for_each. И по логике генерация матрицы должна начать выполняться параллельно. Я хочу сразу отметить, что это возможность последнего стандарта C++17, который был принят в 2017 году. Давайте, наконец, попробуем и посмотрим, как это работает. Запускаем компиляцию. И у нас не компилируется. Смотрим в ошибку компиляции. fatal error: execution: No such file or directiory. Дело в том, что несмотря на то, что стандарт C++17 был принят в 2017 году и в него официально добавили параллельные версии алгоритмов, на момент записи этого видео (а это апрель 2018 года) ни один из ведущих компиляторов C++, то есть Microsoft, GCC и Clang, ни один из этих компиляторов не реализовали поддержку параллельных версий алгоритмов. Поэтому сейчас этим воспользоваться нельзя. Мы не могли об это вам не рассказать, потому что это наше ближайшее будущее, однако продемонстрировать, как это работает и какую пользу это приносит, мы сейчас не можем, потому что реализации ещё нет. Поэтому нужно следить за новостями и ждать, когда в основных компиляторах C++ появится, наконец, поддержка параллельных версий стандартных алгоритмов.