Cómo hacer que este código sea seguro para hilos con openMP? Integración de Monte Carlo bidimensional.
Estoy tratando de aprender la paralelización con openmp.
Este código realiza una integración de Monte Carlo bidimensional.
El tiempo de ejecución del programa (con omp) es de aproximadamente 25 segundos para N = 900 millones.
#include <cmath>
#include <cstdint>
#include <iostream>
#include <omp.h>
#include <random>
double func(double x, double y) {
return sqrt(x+y);
}
using std::cout;
using std::endl;
const double a = 0.0, b = 1.0, c = 3.0, d = 5.0;
const uint64_t N = 900000000;
int main() {
double sum = 0.0;
std::random_device rd;
#pragma omp parallel
{
uint32_t seed;
#pragma omp critical
{
seed = rd();
}
std::mt19937 gen(seed);
std::uniform_real_distribution<double> dist(0.0, 1.0);
#pragma omp for reduction(+ : sum)
for (int64_t i = 0; i < N; i++) {
double x = a + (b - a) * dist(gen);
double y = c + (d - c) * dist(gen);
#pragma omp atomic
sum += func(x, y);
}
}
double ans = sum * (b - a) * (d - c)/ N;
cout << ans << endl;
return 0;
}
¿Cómo puedo convertir esto en un código seguro para hilos (según dijo el profesor que no es seguro para hilos)?</omp.h>
davy.ai
Para convertir el código en thread-safe, necesitamos abordar el problema de múltiples hilos accediendo y modificando la misma variable (
sum
) simultáneamente. Podemos usar una seccióncritical
de OpenMP para asegurar que solo un hilo acceda a la variable a la vez. El código actualizado se muestra a continuación:en el código actualizado, inicializamos una variable local
local_sum
en cada hilo para almacenar la suma local de ese hilo. luego usamos una seccióncritical
para agregar las sumas locales a la variable globalsum
. esto asegura que solo un hilo accede asum
a la vez y evita condiciones de carrera. return=”” 0;=”” }=””="" en="" el="" código="" actualizado,="" inicializamos="" una="" variable="" local="" `local_sum`="" en="" cada="" hilo="" para="" almacenar="" la="" suma="" local="" de="" ese="" hilo.="" luego="" usamos="" una="" sección="" `critical`="" para="" agregar="" las="" sumas="" locales="" a="" la="" variable="" global="" `sum`.="" esto="" asegura="" que="" solo="" un="" hilo="" accede="" a="" `sum`="" a="" la="" vez="" y="" evita="" condiciones="" de=""></endl;
return 0;
}
en el código actualizado, inicializamos una variable local
local_sum
en cada hilo para almacenar la suma local de ese hilo. luego usamos una seccióncritical
para agregar las sumas locales a la variable globalsum
. esto asegura que solo un hilo accede asum
a la vez y evita condiciones de carrera.></omp.h>