es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Optimizar la función de estimación Pi en C++

He escrito un programa que aproxima Pi usando el método de Monte Carlo. Funciona bien, pero me pregunto si puedo hacer que funcione mejor y más rápido, porque al insertar algo como ~n=100000000 y mayores a partir de ese punto, tarda un tiempo en realizar los cálculos e imprimir el resultado.

He imaginado cómo podría intentar aproximarlo mejor haciendo una mediana para los resultados de n, pero considerando lo lento que es mi algoritmo para números grandes, decidí no hacerlo.

Básicamente, la pregunta es: ¿Cómo puedo hacer que esta función funcione más rápido?

Aquí está el código que tengo hasta ahora:

double estimate_pi(double n)
{
    int i;
    double x, y, distance;
    srand((unsigned) time(0));
    double num_point_circle = 0;
    double num_point_total = 0;
    double final;

    for (i = 0; i < n; i++)
    {
        x = (double) rand() / RAND_MAX;
        y = (double) rand() / RAND_MAX;
        distance = sqrt(x * x + y * y);
        if (distance <= 1)
        {
            num_point_circle += 1;
        }
        num_point_total += 1;
    }
    final = ((4 * num_point_circle) / num_point_total);
    return final;
}
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Hay varias formas de optimizar el código actual para hacer que funcione más rápido:

    1. Paralelización: El bucle for puede ejecutarse en paralelo utilizando el multihilo para acelerar cálculos. Esto es particularmente útil para valores grandes de n. Hay varias bibliotecas disponibles que se pueden usar para la paralelización en C++ como OpenMP o std::thread.
    2. Optimización del compilador: El uso de banderas de optimización al compilar el código puede mejorar su rendimiento. Por ejemplo, el uso del nivel de optimización -O3 en g++ puede reducir significativamente el tiempo de ejecución del código.

    3. Evitar cálculos innecesarios: La función sqrt() es una operación computacionalmente costosa, y se llama en cada iteración del bucle for. Podemos optimizar el código calculando la distancia al cuadrado en lugar de la distancia en sí misma. Esto se puede lograr cambiando la línea distance = sqrt(x*x + y*y); a distance = x*x + y*y;. Este cambio simple puede mejorar significativamente el rendimiento del código.

    4. Usar funciones en línea: La función rand() se llama dos veces en cada iteración del bucle for. Podemos mejorar el rendimiento utilizando una función en línea para generar números aleatorios. Esto se puede lograr agregando la siguiente función al principio del código:

      inline double my_rand()
      {
         static unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
         static std::default_random_engine generator(seed);
         static std::uniform_real_distribution<double> distribution(0.0, 1.0);
         return distribution(generator);
      }
      

      Y cambiando las líneas x = (double)rand()/RAND_MAX; y y = (double)rand()/RAND_MAX; a x = my_rand(); y y = my_rand(); respectivamente.

    Al implementar estas optimizaciones, el código puede hacerse más rápido y eficiente, lo que le permite manejar valores más grandes de n sin tomar demasiado tiempo.

Comments are closed.