12 lutego 2020

[C++17] Parallel algorithms

Biblioteka standardowa w C++17 została rozbudowana o algorytmy, których praca może zostać zrównoleglona. O sposobie wykonania decyduje ExecutionPolicy przekazane do funkcji jako argument. Programista musi zapewnić, że funkcja przekazana do "algorytmu", będzie bezpieczna - nie będzie zależności między danymi (np. modyfikowanie danych, które mogą być odczytywane przez inny równoległy wątek). Dobre wytłumaczenie różnic na stackoverflow, a tutaj małe zestawienie:
  • std::execution::seq - standardowe wykonanie sekwencyjne, bez zrównoleglenia.
  • std::execution::par - równoległe wykonanie (choć nie ma obietnicy, że tak się stanie).
  • std::execution::par_unseq - równoległe wykonanie (choć nie ma obietnicy, że tak się stanie). Wymaga silniejszych gwarancji na to że przeplatane wywołanie funkcji będzie bezpieczne także w obrębie jednego wątku. Nowe procesory oferują taką możliwość dzięki instrukcjom do wektoryzacji - SIMD (Single-Instruction, Multiple-Data) parallelism.
Przykład z funkcją std::reduce, która w działaniu przypomina std::accumulate. Zsumowanie wartości w wektorze:
#include <iostream>
#include <numeric>
#include <execution>
#include <vector>

using namespace std;

int main() {
    vector<int> vec{1, 2, 3, 4};

    int result = std::reduce(std::execution::par,
                             begin(vec),
                             end(vec));

    cout << result << endl;
}
W przypadku gcc (9.2.1 20191008) wymagane było zainstalowanie dodatkowej paczki libtbb-dev (Threading Building Blocks).
$ sudo apt-get install libtbb-dev
$ g++ -std=c++17 main.cpp -ltbb
$ ./a.out

10

Brak komentarzy:

Prześlij komentarz