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

Documentos relacionados