Paralelismo en C++ - Parallel STL y más allá
Transcripción
Paralelismo en C++ - Parallel STL y más allá
Paralelismo en C++ Paralelismo en C++ Parallel STL y más allá Luis Miguel Sánchez [email protected] Universidad Carlos III de Madrid 18 de noviembre de 2015 cb e d Luis Miguel Sánchez. ARCOS@uc3m 1/47 Paralelismo en C++ ¿Qué es paralelismo? 1 ¿Qué es paralelismo? 2 STL: Standard Template Library 3 Parallel STL 4 ¿Y ahora que más? cb e d Luis Miguel Sánchez. ARCOS@uc3m 2/47 Paralelismo en C++ ¿Qué es paralelismo? Concurrencia vs. Paralelismo cb e d Luis Miguel Sánchez. ARCOS@uc3m 3/47 Paralelismo en C++ ¿Qué es paralelismo? ¿Cómo funciona el paralelismo? Fuente: https://en.wikipedia.org/wiki/OpenMP cb e d Luis Miguel Sánchez. ARCOS@uc3m 4/47 Paralelismo en C++ ¿Qué es paralelismo? Vectorización Fuente: https: //software.intel.com/en-us/blogs/2012/01/31/vectorization-find-out-what-it-is-find-out-more cb e d Luis Miguel Sánchez. ARCOS@uc3m 5/47 Paralelismo en C++ ¿Qué es paralelismo? Ley de Moore Fuente: http://education.mrsec.wisc.edu/SlideShow/slides/computer/Moores_Law.html cb e d Luis Miguel Sánchez. ARCOS@uc3m 6/47 Paralelismo en C++ ¿Qué es paralelismo? Free lunch is over - Herb Sutter (2004) cb e d Luis Miguel Sánchez. ARCOS@uc3m 7/47 Paralelismo en C++ ¿Qué es paralelismo? Temperatura alcanzada por un procesador Can soon put more transistors on a chip than can afford to turn on. - Patterson 2007 cb e d Luis Miguel Sánchez. ARCOS@uc3m 8/47 Paralelismo en C++ ¿Qué es paralelismo? Temperatura alcanzada por un procesador Can soon put more transistors on a chip than can afford to turn on. - Patterson 2007 cb e d Luis Miguel Sánchez. ARCOS@uc3m 8/47 Paralelismo en C++ ¿Qué es paralelismo? ¿Y cómo utilizo el paralelismo en C++? Frameworks basados en directivas #pragma. OpenMP, OpenACC, OpenSS, etc. Bibliotecas externas TBB, Cilk Plus, PPL, Fast-Flow, SYCL, etc. Biblioteca estándar STL paralelas. cb e d Luis Miguel Sánchez. ARCOS@uc3m 9/47 Paralelismo en C++ STL: Standard Template Library 1 ¿Qué es paralelismo? 2 STL: Standard Template Library 3 Parallel STL 4 ¿Y ahora que más? cb e d Luis Miguel Sánchez. ARCOS@uc3m 10/47 Paralelismo en C++ STL: Standard Template Library Standard Template Library (STL) Originalmente diseñada por Alexander Stepanov. Objetivo original: “la representación más general, más eficiente y más flexible de conceptos”. Representar conceptos separados de forma separada en el código. Combinar conceptos libremente siempre que tenga sentido. Modelo básico: Contenedores: Estructuras que almacenan datos. Iteradores: Permite recorrer contenedores. Algoritmos: Manipulan datos independientemente de contenedores. cb e d Luis Miguel Sánchez. ARCOS@uc3m 11/47 Paralelismo en C++ STL: Standard Template Library Algoritmos en STL Gran variedad: 90 algoritmos. Clasificación: De secuencia: Modificación y no-modificación. Particionamiento, ordenación y búsqueda binaria. Operaciones de conjunto y montículo. Operaciones de mínimo y máximo. Operaciones numéricas. cb e d Luis Miguel Sánchez. ARCOS@uc3m 12/47 Paralelismo en C++ STL: Standard Template Library Ejemplos de uso de las STL Aplica un objeto función a cada elemento de una secuencia. vector<int> v{1,2,3,4,5,6,7,8}; for_each(begin(v), end(v), [](int x) { cout << x; }); Transforma una secuencia en otra aplicando una operación vector<int> v{1,2,3,4,5,6,7,8}; vector<int> w; transform(begin(v), end(v), back_inserter(w), [](int x) {return x*x}); vector<int> z; transform(begin(v), end(v), begin(w), end(w), back_inserter(z), [](int x, int y) { return x+y; }); cb e d Luis Miguel Sánchez. ARCOS@uc3m 13/47 Paralelismo en C++ Parallel STL 1 ¿Qué es paralelismo? 2 STL: Standard Template Library 3 Parallel STL 4 ¿Y ahora que más? cb e d Luis Miguel Sánchez. ARCOS@uc3m 14/47 Paralelismo en C++ Parallel STL Parallel STL roadmap Fuente: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0024r0.html cb e d Luis Miguel Sánchez. ARCOS@uc3m 15/47 Paralelismo en C++ Parallel STL Trabajos anteriores a la especificación Thrust http://thrust.github.io Boost.Compute http://github.com/boostorg/compute Bolt http://github.com/HSA-Libraries/Bolt libstdc++ Parallel Mode http://gcc.gnu.org/onlinedocs/libstdc++/manual/ parallel_mode.html AMP Algorithms Library http://ampalgorithms.codeplex.com cb e d Luis Miguel Sánchez. ARCOS@uc3m 16/47 Paralelismo en C++ Parallel STL ¿Qué algoritmos se incluyen? Fuente: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4507.pdf cb e d Luis Miguel Sánchez. ARCOS@uc3m 17/47 Paralelismo en C++ Parallel STL Versiones de algoritmos Todos los algoritmos paralelos toman como primer parámetro una política de ejecución. Ejemplo: ordenando un vector using namespace std; vector<double> v = read_values(); sort(v.begin(), v.end()); using namespace std::experimental::parallel; sort(seq, v.begin(), v.end()); // Secuencial sort(par, v.begin(), v.end()); // Paralelo sort(par_vec, v.begin(), v.end()); // Paralelo+Vect cb e d Luis Miguel Sánchez. ARCOS@uc3m 18/47 Paralelismo en C++ Parallel STL Politicas de ejecución Una Política de ejecución indica el tipo de paralelismo que se permite en la ejecución de un algoritmo. Secuencial: Sin paralelizar. Tipo: sequential_execution_policy. Objeto global: seq. Paralelo: Paralelizado. Tipo: parallel_execution_policy. Objeto global: par. Paralelo + Vector: Paralelizado y vectorizado. Tipo: parallel_vector_execution_policy. Objeto global: par_vec. Importante: no existe vec. Dinámica: Puede contener cualquier política. Tipo: execution_policy. No hay objeto global. cb e d Luis Miguel Sánchez. ARCOS@uc3m 19/47 Paralelismo en C++ Parallel STL Política de ejecución dinámica Ejemplo: cambiando de política constexpr size_t threshold = 1000; std::vector v = read_values(); using namespace std::experimental::parallel; execution_policy exec = seq; if (v.size() > threshold) { exec = par; } sort(exec, begin(v), end(v)); cb e d Luis Miguel Sánchez. ARCOS@uc3m 20/47 Paralelismo en C++ Parallel STL Ejemplos Buscando una secuencia vector<int> v = get_values_vector(); count_if(par, begin(v), end(v), [](int x) { return x>0; }); auto p = find(par, begin(v), end(v), 0); auto q = find_if(par, begin(v), end(v), [](int x) { return (x>0) && (x<10); } Palindromo const auto pal = equal(par, begin(str), begin(str) + str.length()/2, str.rbegin()); cb e d Luis Miguel Sánchez. ARCOS@uc3m 21/47 Paralelismo en C++ Parallel STL Algoritmos no paralelizados De busqueda binaria (std::binary_search) De monticulo (std::sort_heap) De permutación (std::prev_permutation) De desplazamiento (std::random_shuffle) Numéricos secuenciales (std::accumulate) cb e d Luis Miguel Sánchez. ARCOS@uc3m 22/47 Paralelismo en C++ Parallel STL Más algoritmos: no numéricos Son algoritmos que no requieren que los valores accedidos por los iteradores sean de un tipo numérico. Más generales que los algoritmos numéricos. Algoritmos: for_each(). for_each_n(). cb e d Luis Miguel Sánchez. ARCOS@uc3m 23/47 Paralelismo en C++ Parallel STL For Each Ejemplo long cuenta_primos(const vector<int> & v) { std::atomic<long> count; for_each(par, begin(v), end(v), [&](int x) { if (esprimo(x)) { count++; } }); return count; } cb e d Luis Miguel Sánchez. ARCOS@uc3m 24/47 Paralelismo en C++ Parallel STL Más algoritmos: numéricos Orientados a secuencias numéricas. Algoritmos: reduce: similar a std::accumulate, excepto que se ejecuta fuera de orden exclusive_scan: similar a std::partial_sum, excluyendo al elemento i-esimo de la i-esima suma. inclusive_scan: similar a std::partial_sum, incluyendo al elemento i-esimo en la i-esima suma. transform_reduce: aplica una funcion a todos los elementos y luego realiza una redución. transform_exclusive_scan: aplica una funcion a todos los elementos y luego realiza una operacion de scan excluyente. transform_inclusive_scan: aplica una funcion a todos los elementos y luego realiza una operacion de scan incluyente. También se añaden las versiones sin parámetro de política. cb e d Luis Miguel Sánchez. ARCOS@uc3m 25/47 Paralelismo en C++ Parallel STL Algoritmos numéricos reduce result = init + a[0] + a[1] + ... + a[N-1] exclusive_scan result[i] = init + a[0] + a[1] + ... + a[i-1] inclusive_scan result[i] = init + a[0] + a[1] + ... + a[i] cb e d Luis Miguel Sánchez. ARCOS@uc3m 26/47 Paralelismo en C++ Parallel STL Ejemplos algoritmos numéricos reduce reduce(begin(v), end(v), 0, [](int a, int b) { return a+b; }); Transform reduce auto suma_cuadrados = transform_reduce(begin(v), end(v), [](double x) { return x * x; }, 0, [](double x, double y) { return x + y; } ); cb e d Luis Miguel Sánchez. ARCOS@uc3m 27/47 Paralelismo en C++ Parallel STL ¡Cuidado con el paralelismo! Que se pueda ejecutar en paralelo no significa que siempre sea posible (Thread-safe). Condiciones de carrera deadlocks Ejemplo 1 int comparisons = 0; std::sort(begin, end, [&](int a, int b) { comparisons++; return a < b; }); Ejemplo 2 int a[] = {0,1}; std::vector<int> v; for_each(par, std::begin(a), std::end(a), [&](int i) { v.push_back(i*2+1); }); cb e d Luis Miguel Sánchez. ARCOS@uc3m 28/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo sequencial int x=0; int a[] = {1,2}; for_each(seq, std::begin(a), std::end(a), [&](int) { ++x; }); cb e d Luis Miguel Sánchez. ARCOS@uc3m 29/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo sequencial int x=0; int a[] = {1,2}; for_each(seq, std::begin(a), std::end(a), [&](int) { ++x; }); OK: acceso secuencial cb e d Luis Miguel Sánchez. ARCOS@uc3m 29/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo politica paralela int x=0; int a[] = {1,2}; for_each(par, std::begin(a), std::end(a), [&](int) { ++x; }); cb e d Luis Miguel Sánchez. ARCOS@uc3m 30/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo politica paralela int x=0; int a[] = {1,2}; for_each(par, std::begin(a), std::end(a), [&](int) { ++x; }); Error: accesos no controlados a una variable compartida. cb e d Luis Miguel Sánchez. ARCOS@uc3m 30/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo paralelo con bloqueos int x=0; std::mutex m; int a[] = {1,2}; for_each(par, std::begin(a), std::end(a), [&](int) { m.lock(); ++x; m.unlock(); }); cb e d Luis Miguel Sánchez. ARCOS@uc3m 31/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo paralelo con bloqueos int x=0; std::mutex m; int a[] = {1,2}; for_each(par, std::begin(a), std::end(a), [&](int) { m.lock(); ++x; m.unlock(); }); OK: acceso exclusivo para modificar las variables compartidas. cb e d Luis Miguel Sánchez. ARCOS@uc3m 31/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo paralelo vectorizado int x=0; std::mutex m; int a[] = {1,2}; for_each(par_vec, std::begin(a), std::end(a), [&](int) { m.lock(); ++x; m.unlock(); }); cb e d Luis Miguel Sánchez. ARCOS@uc3m 32/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo paralelo vectorizado int x=0; std::mutex m; int a[] = {1,2}; for_each(par_vec, std::begin(a), std::end(a), [&](int) { m.lock(); ++x; m.unlock(); }); Error: El código del algoritmo no garantiza que pueda ser ejecutado en diferentes hilos de ejecución. cb e d Luis Miguel Sánchez. ARCOS@uc3m 32/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo paralelo vectorizado con atomicos std::atomic<int> x=0; int a[] = {1,2}; for_each(par_vec, std::begin(a), std::end(a), [&](int) { ++x; }); cb e d Luis Miguel Sánchez. ARCOS@uc3m 33/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo paralelo vectorizado con atomicos std::atomic<int> x=0; int a[] = {1,2}; for_each(par_vec, std::begin(a), std::end(a), [&](int) { ++x; }); OK: acceso atómico a los datos. cb e d Luis Miguel Sánchez. ARCOS@uc3m 33/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo mejorado int x = count_if(par_vec, ...); cb e d Luis Miguel Sánchez. ARCOS@uc3m 34/47 Paralelismo en C++ Parallel STL ¡Cuidado con las politicas de ejecución! Ejemplo mejorado int x = count_if(par_vec, ...); OK: Usando algoritmos de alto nivel optimizados. cb e d Luis Miguel Sánchez. ARCOS@uc3m 34/47 Paralelismo en C++ Parallel STL Implementaciones STL paralela Microsoft http://parallelstl.codeplex.com HPX http://stellar-group.github.io/hpx/docs/html/hpx/ manual/parallel.html Codeplay http://github.com/KhronosGroup/SyclParallelSTL HSA http://www.hsafoundation.com/hsa-for-math-science Thibaut Lutz http://github.com/t-lutz/ParallelSTL NVIDIA http://github.com/n3554/n3554 cb e d Luis Miguel Sánchez. ARCOS@uc3m 35/47 Paralelismo en C++ Parallel STL WordCount (I) Cuenta el número de apariciones de cada palabra de un fichero de texto dado. Ejemplo típico en aplicaciones basadas en el paradigma MapReduce. Hace uso de algoritmos de alto nivel: Transform Reduce cb e d Luis Miguel Sánchez. ARCOS@uc3m 36/47 Paralelismo en C++ Parallel STL WordCount (II) Parallel Transform vector<string> palabras; vector<map<string, long>> v; map<string, long> r; ... // Fase MAP std::experimental::parallel::transform(std::experimental::parallel:: par, begin(palabras), end(palabras), back_inserter(v), [](string s) { char chars[] = ",.;:()!?’"; for (auto i : chars) s.erase(std::remove(s.begin(), s.end(), i), s.end()); map<string, long> r; r[s] = 1L; return r; }); cb e d Luis Miguel Sánchez. ARCOS@uc3m 37/47 Paralelismo en C++ Parallel STL WordCount (y III) Parallel Reduce // Fase REDUCE r = std::experimental::parallel::reduce(std::experimental::parallel::par , v.begin(), v.end(), std::map<string, long>(), [](map<string, long> x, map<string, long> y) { for (auto & z : y) { x[z.first] += z.second; } return x; }); cb e d Luis Miguel Sánchez. ARCOS@uc3m 38/47 Paralelismo en C++ ¿Y ahora que más? 1 ¿Qué es paralelismo? 2 STL: Standard Template Library 3 Parallel STL 4 ¿Y ahora que más? cb e d Luis Miguel Sánchez. ARCOS@uc3m 39/47 Paralelismo en C++ ¿Y ahora que más? Lista de deseos para el paralelismo en C++ Soporte acceleradores (GPU) Paralelismo de tareas Patrones de diseño paralelos cb e d Luis Miguel Sánchez. ARCOS@uc3m 40/47 Paralelismo en C++ ¿Y ahora que más? Welcome to the jungle - Herb Sutter (2011) Fuente: http://herbsutter.com/welcome-to-the-jungle/ cb e d Luis Miguel Sánchez. ARCOS@uc3m 41/47 Paralelismo en C++ ¿Y ahora que más? ¡Ahora vas y lo implementas! Ejemplos sort(vectorize_in_this_thread, vec.begin(), vec.end()); sort(submit_to_my_thread_pool, vec.begin(), vec.end()); sort(execute_on_that_gpu, vec.begin(), vec.end()); sort(offload_to_my_fpga, vec.begin(), vec.end()); sort(send_to_the_cloud, vec.begin(), vec.end()); sort(launder_through_botnet, vec.begin(), vec.end()); sort(this_thread::par, data.begin(), data.end()); sort(this_thread::vec, data.begin(), data.end()); my_executor my_exec = ...; std::sort(par.on(my_exec), data.begin(), data.end()); Fuentes: Parallelizing the Standard Algorithms Library - Jared Hoberock (NVIDIA) Parallel Algorithms Need Executors (N4406) cb e d Luis Miguel Sánchez. ARCOS@uc3m 42/47 Paralelismo en C++ ¿Y ahora que más? Paralelismo de tareas Quicksort: secuencial void quicksort( int *v, int start, int end) { if (start < end) { int pivot = partition(v, start, end); quicksort(v, start, pivot - 1); quicksort(v, pivot + 1, end); } } cb e d Luis Miguel Sánchez. ARCOS@uc3m 43/47 Paralelismo en C++ ¿Y ahora que más? Paralelismo de tareas Quicksort: std::threads void quicksort(int *v, int start, int end) { if (start < end) { int pivot = partition(v, start, end); std::thread t1([&] { quicksort(v, start, pivot - 1); }); std::thread t2([&] { quicksort(v, pivot + 1, end); }); t1.join(); t2.join(); } } cb e d Luis Miguel Sánchez. ARCOS@uc3m 44/47 Paralelismo en C++ ¿Y ahora que más? Paralelismo de tareas Quicksort: tareas (N3832) void quicksort(int *v, int start, int end) { if (start < end) { task_region([&] (auto& r) { int pivot = partition(v, start, end); r.run([&] { quicksort(v, start, pivot - 1); }); r.run([&] { quicksort(v, pivot + 1, end); }); }); } } Fuente: Parallelism in the Standard C++: What to Expect in C++ 17 - Artur Laksberg cb e d Luis Miguel Sánchez. ARCOS@uc3m 45/47 Paralelismo en C++ ¿Y ahora que más? Patrones de diseño paralelos Fuente: http://parallelbook.com/ cb e d Luis Miguel Sánchez. ARCOS@uc3m 46/47 Paralelismo en C++ ¿Y ahora que más? Paralelismo en C++ Parallel STL y más allá Luis Miguel Sánchez [email protected] Universidad Carlos III de Madrid 18 de noviembre de 2015 cb e d Luis Miguel Sánchez. ARCOS@uc3m 47/47