Semana 3: Ejemplos de paralelización¶
Ejemplos de clase¶
https://github.com/cardel/infra-2025
Threads¶
¿Que es?
Nos permite especificar el numero de hilos a los cuales vamos a partir un proceso
El número depende de:
- Capacidad de la maquina
- Si estamos en una virtualización o no
- Del tamaño de la tarea (tareas pequeñas es mejor hacerlas secuencial)
- De la gestión de procesos del S.O
Aspectos
rutina:
g++ -o <exe> <archivo.cpp> -lpthread
#include <thread>
thread nombre(funcion, args.....); //Sin retorno
thread nombre([&salida](){salida = funcion(args...)}); //Un solo retorno
thread nombre(funcion, arg1, ref(argn),...);
Aquí tienes un ejemplo de cómo calcular la norma de un vector usando 4 hilos en C++:
#include <iostream>
#include <vector>
#include <thread>
#include <cmath>
#include <chrono>
using namespace std;
const int VECTOR_SIZE = 10000000; // Vector grande para mejor demostración
vector<double> v(VECTOR_SIZE, 2.0); // Inicializamos con 2.0 para ejemplo
double partial_results[4] = {0,0,0,0};
void calculatePartialNorm(int start, int end, int thread_id) {
double sum = 0.0;
for(int i = start; i < end; i++) {
sum += v[i] * v[i];
}
partial_results[thread_id] = sum;
}
int main() {
// Crear 4 hilos para calcular la norma
thread t1(calculatePartialNorm, 0, VECTOR_SIZE/4, 0);
thread t2(calculatePartialNorm, VECTOR_SIZE/4, VECTOR_SIZE/2, 1);
thread t3(calculatePartialNorm, VECTOR_SIZE/2, 3*VECTOR_SIZE/4, 2);
thread t4(calculatePartialNorm, 3*VECTOR_SIZE/4, VECTOR_SIZE, 3);
// Esperar a que todos los hilos terminen
t1.join();
t2.join();
t3.join();
t4.join();
// Sumar resultados parciales y calcular raíz cuadrada
double final_result = sqrt(partial_results[0] + partial_results[1] +
partial_results[2] + partial_results[3]);
cout << "La norma del vector es: " << final_result << endl;
return 0;
}
Para compilar el programa, usa el siguiente comando:
g++ -o norma norma.cpp -lpthread
Este ejemplo divide el vector en 4 partes igualesy cada hilo procesa su parte correspondiente. La división se hace en segmentos de 0 a n/4, n/4 a n/2, n/2 a 3n/4, y 3n/4 a n.
TBB¶
#include <iostream>
#include <tbb/parallel_for.h>
#include <tbb/blocked_range.h>
#include <tbb/parallel_reduce.h>
Paralelización
- No definimos un número dado de hilos
- Vamos utilizar las estructuras que nos brinda la librería
For paralelo
tbb::parallel_for(tbb::blocked_range<int>(start, end), [&](tbb::blocked_range<int> r) {
- Genera un rango entre o y size
- Se crea un iterador r el cual va realizar la partición
Reduce paralelo
void sumaTBB(int start, int end, long &sum) {
sum = tbb::parallel_reduce(tbb::blocked_range<int>(start, end), 0L, [&](tbb::blocked_range<int> r, long init) {
long sum = init;
for (int i = r.begin(); i < r.end(); i++) {
sum += v[i];
}
return sum;
},std::plus<long>());
- Se genera un rango entre 0 y size
2.. Se tiene el iterador r tal cual en el for paralelo
- Vamos a hacer resultados parciales
- Con
std::plus<long>());
Vamos a reducir los valores parciales (sumando)
Resumen¶
Esta página describe dos métodos principales de paralelización:
1. Threads (Hilos)
- Son una forma de dividir un proceso en múltiples hilos
- La elección del número de hilos depende de factores como la capacidad de la máquina, virtualización, tamaño de la tarea y gestión del SO
- Se implementa en C++ usando la librería thread y requiere la flag -lpthread para compilar
2. TBB (Thread Building Blocks)
- No requiere definir un número específico de hilos
- Utiliza estructuras propias de la librería
- Ofrece herramientas como parallel_for y parallel_reduce para paralelización
La página incluye ejemplos prácticos de implementación, incluyendo un caso detallado de cálculo de la norma de un vector usando threads.