gstvrmrlpz / energy

Energy consumption of EC implementations in several programming languages
GNU General Public License v3.0
1 stars 0 forks source link

Sacar fuera la generación de cromosomas #2

Closed JJ closed 3 months ago

JJ commented 3 months ago

Si puede ser, debería ser una función independiente que se incluyera en el main. Y ya puestos, me gusta testear todo. Si quieres puedo hacerlo yo, una vez que las funciones estén en su propio módulo.

gstvrmrlpz commented 3 months ago

Ya está divididos los cuatro eventos. Ahora main queda de esta forma para todas las versiones:

int main(int argc, char *argv[])
{
    population p(POPULATION_SIZE);

    initialize(p);
    mutate(p);
    crossover(p);
    return evaluate(p);
}
JJ commented 3 months ago

De aquí yo diría que lo único que queda pendiente es que sólo haya dos niveles: con generación y con una operación.

gstvrmrlpz commented 3 months ago

La función main se hizo común para todas las versiones. ¿Es necesario hacerle algún cambio más?

template<typename population> int common_main(int argc, char *argv[])
{
    std::size_t step = std::numeric_limits<std::size_t>::max(), value = 0;

    if (argc > 1)
        step = std::atoi(argv[1]);

    std::cout << "step = " << step << '\n';

    if (step == 0)
        return value;

    population p(POPULATION_SIZE);

    if (step == 1)
        return value;

    initialize(p);

    if (step == 2)
        return value;

    mutate(p);

    if (step == 3)
        return value;

    crossover(p);

    if (step == 4)
        return value;

    value = evaluate(p);

    return value;
}
JJ commented 3 months ago

La función main se hizo común para todas las versiones. ¿Es necesario hacerle algún cambio más?

template<typename population> int common_main(int argc, char *argv[])
{
    std::size_t step = std::numeric_limits<std::size_t>::max(), value = 0;

    if (argc > 1)
        step = std::atoi(argv[1]);

    std::cout << "step = " << step << '\n';

    if (step == 0)
        return value;

    population p(POPULATION_SIZE);

    if (step == 1)
        return value;

    initialize(p);

    if (step == 2)
        return value;

    mutate(p);

    if (step == 3)
        return value;

    crossover(p);

    if (step == 4)
        return value;

    value = evaluate(p);

    return value;
}

Sigue teniendo 4 niveles, no dos: uno para inicializar, otro para el resto. Además, como te comenté, no se trata de aplicar a todo el bucle una, luego otra, luego otra: un solo bucle, aplicar las tres operaciones.

gstvrmrlpz commented 3 months ago

Si da igual perder las mediciones individuales para mutación, cruce y evaluación se puede hacer. En todo caso debería haber como mínimo 3 fases para poder descartar la sobrecarga de inicialización y finalización de la biblioteca de c++. De esta forma quedaría: 0) libstdc++ 1) inicialización 2) AG

¿Te parece bien así?

JJ commented 3 months ago

La sobrecarga en la inicialización la descartamos restando de las medidas la media de inicialización de los cromosomas. Por tanto, una fase para inicialización. Pero tendría que haber dos programas: uno para evaluar sobre los 40000 cromosomas mutación + crossover + maxones y otra para HIFF. energy-languages-lion-2024.pdf Te adjunto lo que hicimos para LION18, y con lo que habría que comparar.

gstvrmrlpz commented 3 months ago

¿Te parece bien algo así?

template<typename chromosome> int common_main(int argc, char *argv[])
{
    std::size_t step = std::numeric_limits<std::size_t>::max(), value = 0;

    if (argc > 1)
        step = std::atoi(argv[1]);

    if (step == 0)
        return value;

    std::vector<chromosome> population(POPULATION_SIZE);

    for (std::size_t i = 0; i < population.size(); i += 2)
    {
        initialize(population[i]);
        initialize(population[i + 1]);
        mutate(population[i]);
        mutate(population[i + 1]);
        crossover(population[i], population[i + 1]);
        value += evaluate(population[i]) + evaluate(population[i + 1]);
    }

    return value;
}
JJ commented 3 months ago

¿Te parece bien algo así?


template<typename chromosome> int common_main(int argc, char *argv[])
{
    std::size_t step = std::numeric_limits<std::size_t>::max(), value = 0;

    if (argc > 1)
        step = std::atoi(argv[1]);

    if (step == 0)
        return value;

    std::vector<chromosome> population(POPULATION_SIZE);

    for (std::size_t i = 0; i < population.size(); i += 2)
    {
        initialize(population[i]);
        initialize(population[i + 1]);

La intención de este issue es que se pueda usar la inicialización de los cromosomas como medida base, que descuente no solo lo que tarda en sí esa inicialización sino también el fondo de overhead del ordenador. Por lo tanto, esta inicialización tendría que estar en su propio bucle, y el step tendría que terminar aquí.

El step 1 aplicaría los tres operadores a los cromosomas ya inicializados.

JJ commented 3 months ago

Si usas un PR puedo hacer sugerencias de código sobre el mismo que se pueden incorporar a la rama.

gstvrmrlpz commented 3 months ago

¿Qué es eso de PR?... Que soy muy nuevo en esto de git...

gstvrmrlpz commented 3 months ago

ya he sacado la inicialización a otro bucle

gstvrmrlpz commented 3 months ago

Lo he dejado en versiones de los ficheros acabados en 2 porque todavía no me llevo bien con las ramas. Falta implementar algunas de las versiones de HIFF e integrarlo, después cambiaré por las versiones definitivas.

JJ commented 3 months ago

¿Qué es eso de PR?... Que soy muy nuevo en esto de git...

Pull Request. Haces una rama, subes la rama, abres un pull request para que el resto de la gente examine la rama. A ver, nuevo, nuevo, tampoco, ¿no?

JJ commented 3 months ago

En todo caso, en los mensajes de commit puedes poner el número de este issue (#2) o el que sea para que enlacen directamente aquí (y notifiquen a quien participa en el issue)

gstvrmrlpz commented 3 months ago

Hace muchos años que no uso git de verdad, no solo para hacer clone.

Ya he integrado los cambios en main y hiff solo para la versión string... te dejo unos resultados:

gustavo@casa:~/escritorio/energy/c++$ make test
------------------------------------------------
     program      length   energy(J)     time(s)
------------------------------------------------
      bitset         512       35,85    1,115925
      bitset        1024       35,68     1,11629
      bitset        2048       36,80    1,114279
     dbitset         512       36,02     1,11707
     dbitset        1024       36,71     1,11533
     dbitset        2048       35,73    1,116086
      string         512       34,35    1,102741
      string        1024       33,79    1,101899
      string        2048       34,58    1,102023
 string-hiff         512      128,25     3,98274
 string-hiff        1024      128,32     3,98507
 string-hiff        2048      135,46     4,00595
      vector         512       35,49    1,147702
      vector        1024       37,26     1,15190
      vector        2048       36,34    1,150709
JJ commented 3 months ago

Igual habría que hacer algún tipo de filtrado sobre qué se va a usar HIFF. En todo caso, estás metiendo en una tabla cosas diferentes... Y el resto de los resultados son muy parecidos, habría que ver analizando los resultados individuales si hay diferencia significativa. A priori, yo diría que la representación "no compacta", el string, tarda algo menos que el resto y consume menos energía. Pero habría que eliminar de ahí la "línea base" de generación de cromosomas.

gstvrmrlpz commented 3 months ago

¿Me puedes aclarar cual de los dos puntos de salida es el que te interesa?

std::size_t step = std::numeric_limits<std::size_t>::max(), value = 0;

    if (argc > 1)
        step = std::atoi(argv[1]);

    if (step == 0)
        return value;

    std::vector<chromosome> population(POPULATION_SIZE);

    for (std::size_t i = 0; i < population.size(); ++i)
        initialize(population[i]);

    if (step == 1)
        return value;

    for (std::size_t i = 0; i < population.size(); i += 2)
    {
        mutate(population[i]);
        mutate(population[i + 1]);
        crossover(population[i], population[i + 1]);
        value += evaluate(population[i]) + evaluate(population[i + 1]);
    }

    return value;
gstvrmrlpz commented 3 months ago

he escogido el segundo y lo he simplificado de forma que ejecutar el programa pasando cualquier parámetro lo haga finalizar tras la inicialización:

template<typename chromosome> int common_main(int argc, char *argv[])
{
    std::size_t value = 0;

    std::vector<chromosome> population(POPULATION_SIZE);

    for (std::size_t i = 0; i < population.size(); ++i)
        initialize(population[i]);

    if (argc != 1)
        return value;

    for (std::size_t i = 0; i < population.size(); i += 2)
    {
        mutate(population[i]);
        mutate(population[i + 1]);
        crossover(population[i], population[i + 1]);
        value += evaluate(population[i]) + evaluate(population[i + 1]);
    }

    return value;
}
gstvrmrlpz commented 3 months ago

pequeña prueba:

gustavo@casa:~/escritorio/energy/c++$ make init
------------------------------------------------------------------------
     program      length         opt   energy(J)     time(s)         run
------------------------------------------------------------------------
      bitset         512         -O2        8,65 0,263075802  1720092527
      bitset         512         -O2        9,60 0,269661140  1720092528
      bitset         512         -O2        8,90 0,266998451  1720092530
      bitset         512         -O2        8,80 0,263896472  1720092531
      bitset         512         -O2        8,60 0,263482812  1720092532
      bitset         512         -O2        8,76 0,263880562  1720092533
      bitset         512         -O2        8,95 0,267956750  1720092534
      bitset         512         -O2        9,37 0,266702781  1720092535
      bitset         512         -O2        8,84 0,266139041  1720092537

gustavo@casa:~/escritorio/energy/c++$ make full
------------------------------------------------------------------------
     program      length         opt   energy(J)     time(s)         run
------------------------------------------------------------------------
      bitset         512         -O2        9,44 0,282508345  1720092542
      bitset         512         -O2        9,35 0,282187066  1720092543
      bitset         512         -O2        9,44 0,283340935  1720092544
      bitset         512         -O2        9,44 0,282035216  1720092545
      bitset         512         -O2        9,46 0,285881144  1720092546