Generación de cromosomas en C++
#include <tr2/dynamic_bitset>
#include <random>
std::vector<std::tr2::dynamic_bitset<>>&
generate_chromosomes(unsigned int number_of_elements, unsigned int length){
std::minstd_rand engine;
static std::vector<std::tr2::dynamic_bitset<>> population;
population.resize(number_of_elements);
for (unsigned i = 0; i < number_of_elements; ++i)
{
std::tr2::dynamic_bitset<> bits(length);
for (unsigned i = 0; i < length; ++i)
bits[i] = engine() & 1;
population[i] = bits;
}
return population;
}
El primer highlight es para la parametrización
de la función; diferentes tamaños actuarán de forma diferente, y
habrá comportamientos no lineales cuando se salga de la caché, por
ejemplo. La función está modularizada, para poder analizarla
de forma independiente
Compilamos con
g++-14
-march=native
-std=c++2a
-Wall
chromosomes.cc generate_chromosomes.cc -o chromosomes
Hay que medir las prestaciones
#!/usr/bin/env sh
FILENAME=$1
for i in 512 1024 2048
do
echo "Size ${i}"
OUTPUT="${FILENAME}-${i}.json"
echo "Saving to ${OUTPUT}"
pumas run -i 100 --json > $OUTPUT &
for j in $(seq 15)|
do
C++/chromosomes $i
done
kill $!
done
Midiendo en un Mac
cat test-512.json | jq ". | .metrics.consumption"
{
"ane_w": 0,
"cpu_w": 4.5013532638549805,
"gpu_w": 0.02891661413013935,
"package_w": 4.530270099639893
}
En un M2 no hay muchas más alternativas. Otros programas como pinpoint o perf son mucho más fáciles de usar
Más fácil con pinpoint
sub process_pinpoint_output {
my $output = shift;
if ($output !~ /0.00\s+J/) {
my ( $gpu, $pkg ) = $output =~ /(\d+\.\d+)\s+J/g;
my ( $seconds ) = $output =~ /(\d+\.\d+) seconds/;
return $gpu, $pkg,$seconds;
} else {
return 0,0,0;
}
}
Hay que instrumentar la medición de consumo
Y trabajar con estadísticas
Dado que hay una multitud de factores en los sistemas modernos que influyen en la energía, desde el propio programa hasta lo que se esté ejecutando y la temperatura ambiente, es necesario trabajar con medias
Esta operación común permite establecer la línea base
Pero nos interesa una función específica
Midiendo operaciones específicas
import { hashify } from "https://deno.land/x/saco@v0.0.2/index.js";
import { countOnes, generateChromosomes } from "../lib/utils.js";
const size = Deno.args[0];
const NUMBER_OF_CHROMOSOMES = 40000;
console.log("Size ", size);
const population = generateChromosomes(size, NUMBER_OF_CHROMOSOMES);
const fitnessArray = [];
population.forEach((c) => {
fitnessArray.push(countOnes(c));
});