updated benchmark script and beginning method 5
This commit is contained in:
parent
41cbb90213
commit
4201e5476e
@ -23,6 +23,8 @@ enable_cxx_compiler_flag_if_supported("-Wpedantic")
|
||||
enable_cxx_compiler_flag_if_supported("-pedantic")
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
enable_cxx_compiler_flag_if_supported("-g")
|
||||
enable_cxx_compiler_flag_if_supported("-pg")
|
||||
enable_cxx_compiler_flag_if_supported("-finstrument-functions")
|
||||
else()
|
||||
enable_cxx_compiler_flag_if_supported("-O3")
|
||||
enable_cxx_compiler_flag_if_supported("-flto")
|
||||
|
@ -1,20 +1,29 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
# This script was written to work with the fish shell. If you do not have the
|
||||
# fish shell installed on your system, please install it before executing this
|
||||
# script.
|
||||
# The results will be stored in the output file `results.txt`
|
||||
|
||||
set nb_amelioration 10 50 100 200 500 1000
|
||||
set nb_execution 200 100 50 20 10 5
|
||||
set available_methods 1 2 3
|
||||
set available_methods 1 2 3 4
|
||||
set output results.txt
|
||||
|
||||
rm -f $output
|
||||
|
||||
for method in $available_methods
|
||||
for i in (seq (count $nb_execution))
|
||||
perf stat -r $nb_execution[$i] -B ./build/bin/genetic-image -i ./img/mahakala-monochrome.jpg -n $nb_amelioration[$i] -m $method ^| grep -iE "counter|elapsed" >> $output
|
||||
echo "" >> $output
|
||||
set nb_options (count $nb_execution)
|
||||
echo "Method $method:" >> $output
|
||||
echo "| / | < | < |" >> $output
|
||||
echo "| Nb d’améliorations | Nb d’exécutions | Temps d’exécution (s) |" >> $output
|
||||
echo "|--------------------+-----------------+-----------------------|" >> $output
|
||||
for i in (seq $nb_options)
|
||||
set total_exec_time 0
|
||||
set startexec (date +%s.%N)
|
||||
for j in $nb_execution[$i]
|
||||
./build/bin/genetic-image -i ./img/mahakala-monochrome.jpg \
|
||||
-n $nb_amelioration[$i] -m $method
|
||||
end
|
||||
set endexec (date +%s.%N)
|
||||
set total_exec_time (math "$total_exec_time+($endexec-$startexec)/$i")
|
||||
echo "|$nb_amelioration[$i]|$nb_execution[$i]|$total_exec_time|" >> $output
|
||||
end
|
||||
echo "" >> $output
|
||||
end
|
||||
|
@ -43,6 +43,8 @@ void method2(cv::Mat const&, cv::Mat&, int);
|
||||
|
||||
void method3(cv::Mat const&, cv::Mat&, int);
|
||||
|
||||
void method4(cv::Mat const&, cv::Mat&, int);
|
||||
void method4(cv::Mat const&, cv::Mat&, int, bool);
|
||||
|
||||
void method5(cv::Mat const&, cv::Mat&, int, int, bool);
|
||||
|
||||
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_METHODS_HH_ */
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <filesystem>
|
||||
#include <tuple>
|
||||
|
||||
[[nodiscard]] auto parse_args(int, char**)
|
||||
-> std::tuple<std::filesystem::path, std::filesystem::path, int, int, bool>;
|
||||
[[nodiscard]] auto parse_args(int, char**) -> std::
|
||||
tuple<std::filesystem::path, std::filesystem::path, int, int, int, bool, bool>;
|
||||
|
||||
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_PARSEARGS_HH_ */
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 42 KiB |
Binary file not shown.
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 26 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
@ -39,10 +39,10 @@ $$\sqrt{\sum_{i=0}^n(v_i - w_i)^2}$$
|
||||
~V~ étant le vecteur de pixels de l’image de référence, ~W~ étant le vecteur de
|
||||
pixels de l’image générée, et ~n~ la taille de ces deux vecteurs.
|
||||
|
||||
Les tests de temps sont réalisés sur un Thinkpad x220, disposant d’un processeur
|
||||
Intel® Core™ i5-2540M à 2.6GHz, composé de deux cœurs supportant chacun deux
|
||||
threads, et de 4Go de RAM. Le programme est compilé avec les options
|
||||
d’optimisation ~-O3~ et ~-flto~.
|
||||
Les tests de temps sont réalisés sur un Lenovo Ideapad Y700, disposant d’un
|
||||
processeur Intel® Core™ i7-6700HQ à 2.6GHz et un turbo à 3.5GHz, composé de
|
||||
quatre cœurs supportant chacun deux threads, et de 16Go de RAM. Le programme est
|
||||
compilé avec les options d’optimisation ~-O3~ et ~-flto~.
|
||||
|
||||
Voici également ci-dessous la liste des options et arguments possibles
|
||||
concernant l’exécution du logiciel.
|
||||
@ -57,21 +57,12 @@ concernant l’exécution du logiciel.
|
||||
-v [ --verbose ] Enables verbosity
|
||||
#+end_src
|
||||
|
||||
Voici la ligne de commande utilisée depuis le répertoire ~build~ afin de pouvoir
|
||||
obtenir un temps d’exécution :
|
||||
#+begin_src shell
|
||||
perf stat -r {nombreExécutions} -B ./bin/genetic-image \
|
||||
-i ../img/mahakala-monochrome.jpg -o output.png \
|
||||
-n {nombreIterations} -m 1
|
||||
#+end_src
|
||||
Voici le script grâce auquel les valeurs de temps d’exécution ont été obtenues :
|
||||
|
||||
Les deux éléments entre accolades sont à remplacer par leur valeur, par exemple
|
||||
afin d’exécuter dix fois le programme avec vingt améliorations, il faudrait
|
||||
exécuter ceci :
|
||||
#+begin_src shell
|
||||
perf stat -r 1 -B ./bin/genetic-image \
|
||||
-i ../img/mahakala-monochrome.jpg -o output.png -n 20 -m 1
|
||||
#+end_src
|
||||
#+INCLUDE: ../benchmarks.fish src shell -n
|
||||
|
||||
Quelques-unes de ces lignes commençasont là uniquement pour de la mise en forme des
|
||||
données afin que je puisse
|
||||
|
||||
** Méthode naïve
|
||||
|
||||
@ -86,15 +77,15 @@ de référence.
|
||||
Voici les moyennes de temps d’exécution selon le nombre d’itérations réussies
|
||||
sur le nombre d’exécutions indiqué.
|
||||
|
||||
| / | < | < | < |
|
||||
| Nb d’améliorations | Temps d’exécution (s) | Variation (s) | Nb d’exécutions |
|
||||
|--------------------+-----------------------+---------------+-----------------|
|
||||
| 10 | 0.060847 | 0.000498 | 200 |
|
||||
| 50 | 0.29823 | 0.00453 | 100 |
|
||||
| 100 | 0.7093 | 0.0135 | 50 |
|
||||
| 200 | 1.9584 | 0.0559 | 20 |
|
||||
| 500 | 8.739 | 0.291 | 10 |
|
||||
| 1000 | 27.930 | 0.582 | 5 |
|
||||
| / | < | < |
|
||||
| Nb d’améliorations | Nb d’exécutions | Temps d’exécution (s) |
|
||||
|--------------------+-----------------+-----------------------|
|
||||
| 10 | 200 | 0.065881 |
|
||||
| 50 | 100 | 0.130041 |
|
||||
| 100 | 50 | 0.186012 |
|
||||
| 200 | 20 | 0.385982 |
|
||||
| 500 | 10 | 1.437486 |
|
||||
| 1000 | 5 | 3.608983 |
|
||||
|
||||
Naturellement, la variation en temps d’exécution croît en même temps que le
|
||||
nombre d’améliorations nécessaires à apporter à l’image à améliorer, dû à la
|
||||
@ -120,17 +111,17 @@ de rapidité à l’exécution. Cette méthode est celle implémentée dans la f
|
||||
Voici les moyennes de temps d’exécution selon le nombre d’itérations réussies
|
||||
sur le nombre d’exécutions indiqué.
|
||||
|
||||
| / | < | < | < |
|
||||
| Nb d’améliorations | Temps d’exécution (s) | Variation (s) | Nb d’exécutions |
|
||||
|--------------------+-----------------------+---------------+-----------------|
|
||||
| 10 | 0.074951 | 0.000533 | 200 |
|
||||
| 50 | 0.26385 | 0.00401 | 100 |
|
||||
| 100 | 0.6385 | 0.0148 | 50 |
|
||||
| 200 | 1.6145 | 0.0348 | 20 |
|
||||
| 500 | 6.747 | 0.235 | 10 |
|
||||
| 1000 | 19.608 | 0.327 | 5 |
|
||||
| / | < | < |
|
||||
| Nb d’améliorations | Nb d’exécutions | Temps d’exécution (s) |
|
||||
|--------------------+-----------------+-----------------------|
|
||||
| 10 | 200 | 0.072979 |
|
||||
| 50 | 100 | 0.114426 |
|
||||
| 100 | 50 | 0.157965 |
|
||||
| 200 | 20 | 0.290475 |
|
||||
| 500 | 10 | 0.785426 |
|
||||
| 1000 | 5 | 2.664046 |
|
||||
|
||||
On peut remarquer une amélioration dans la rapidité d’exécution du logiciel.
|
||||
On peut remarquer une amélioration quant à la rapidité d’exécution du logiciel.
|
||||
Cependant, le résultat n’est pas aussi important qu’escompté. Je suppose que
|
||||
cela est dû au fait que l’algorithme précédent peut considérer un rapprochement
|
||||
d’une zone déjà colorée vers la couleur d’origine comme une amélioration, avec
|
||||
@ -164,15 +155,15 @@ $$taille=Rand([\![tailleMinimale;tailleMaximale[\![)$$
|
||||
Voici les moyennes de temps d’exécution selon le nombre d’itérations réussies
|
||||
sur le nombre d’exécutions indiqué.
|
||||
|
||||
| / | < | < | < |
|
||||
| Nb d’améliorations | Temps d’exécution (s) | Variation (s) | Nb d’exécutions |
|
||||
|--------------------+-----------------------+---------------+-----------------|
|
||||
| 10 | | | 200 |
|
||||
| 50 | | | 100 |
|
||||
| 100 | | | 50 |
|
||||
| 200 | | | 20 |
|
||||
| 500 | | | 10 |
|
||||
| 1000 | | | 5 |
|
||||
| / | < | < |
|
||||
| Nb d’améliorations | Nb d’exécutions | Temps d’exécution (s) |
|
||||
|--------------------+-----------------+-----------------------|
|
||||
| 10 | 200 | 0.082068 |
|
||||
| 50 | 100 | 0.244236 |
|
||||
| 100 | 50 | 0.418075 |
|
||||
| 200 | 20 | 1.453703 |
|
||||
| 500 | 10 | 4.777205 |
|
||||
| 1000 | 5 | 20.33209 |
|
||||
|
||||
Cette version du logiciel est nettement plus lente que ses versions précédentes
|
||||
du fait de la contrainte de taille pour les formes pouvant potentiellement
|
||||
@ -196,14 +187,70 @@ résultats sont récupérés et évalués, et parmi les résultats améliorant l
|
||||
générée, celle avec le meilleur score est conservée. Cela permet ainsi de
|
||||
multiplier les chances d’avoir une amélioration de l’image par tentative.
|
||||
|
||||
Voici les benchmarks d’exécution de cette méthode sans contrôle de la taille des
|
||||
formes aléatoires :
|
||||
| / | < | < |
|
||||
| Nb d’améliorations | Nb d’exécutions | Temps d’exécution (s) |
|
||||
|--------------------+-----------------+-----------------------|
|
||||
| 10 | 200 | 0.080525 |
|
||||
| 50 | 100 | 0.139892 |
|
||||
| 100 | 50 | 0.169113 |
|
||||
| 200 | 20 | 0.273342 |
|
||||
| 500 | 10 | 0.610812 |
|
||||
| 1000 | 5 | 1.403816 |
|
||||
|
||||
Et voici les benchmarks d’exécution de cette même méthode avec contrôle de la
|
||||
taille des formes aléatoires :
|
||||
| / | < | < |
|
||||
| Nb d’améliorations | Nb d’exécutions | Temps d’exécution (s) |
|
||||
|--------------------+-----------------+-----------------------|
|
||||
| 10 | 200 | 0.085981 |
|
||||
| 50 | 100 | 0.156099 |
|
||||
| 100 | 50 | 0.29183 |
|
||||
| 200 | 20 | 0.59844 |
|
||||
| 500 | 10 | 2.513782 |
|
||||
| 1000 | 5 | 6.457168 |
|
||||
|
||||
Pour résumer, ces deux tableaux montrent la parallélisation de la seconde
|
||||
méthode et de la troisième méthode respectivement via des threads
|
||||
concurrentiels. On peut remarquer que le temps d’exécution s’est nettement
|
||||
amélioré, avec un temps d’exécution à peu près deux fois plus rapide pour
|
||||
l’exécution sans contrôle de taille des formes que la seconde méthode, et
|
||||
pouvant être jusqu’à trois fois plus rapide que la troisième méthode avec le
|
||||
contrôle de la taille des formes activée. On a donc une véritable amélioration
|
||||
significative avec cette nouvelle version parallèle.
|
||||
|
||||
** Collaboration entre threads
|
||||
|
||||
Une différente approche au parallélisme peut être réalisée : plutôt que
|
||||
d’essayer de mettre en concurrence plusieurs threads, il serait possible
|
||||
d’essayer de plutôt les mettre en collaboration. Cela implique par exemple de
|
||||
diviser l’image d’entrée en plusieurs zones sur laquelle chacun des threads
|
||||
lancés travailleraient, appliquant chacun le nombre d’améliorations demandé sur
|
||||
sa zone dédiée. Puis, une fois que chacun des threads a terminé son travail, les
|
||||
différentes zones sont unifiées en une seule image.
|
||||
|
||||
* Annexes
|
||||
** Images
|
||||
*** Image de référence
|
||||
#+CAPTION: Image de référence utilisée pour les tests du logiciel
|
||||
[[../img/mahakala-monochrome.jpg]]
|
||||
*** Méthode 1
|
||||
#+CAPTION: Image générée à partir de ~img/mahakala-monochrome.png~ avec 2000 améliorations avec la première méthode
|
||||
[[./output1.png]]
|
||||
|
||||
*** Méthode 2
|
||||
#+CAPTION: Image générée à partir de ~img/mahakala-monochrome.png~ avec 2000 améliorations avec la seconde méthode
|
||||
[[./output2.png]]
|
||||
|
||||
*** Méthode 3
|
||||
#+CAPTION: Image générée à partir de ~img/mahakala-monochrome.png~ avec 2000 améliorations avec la troisième méthode
|
||||
[[./output3.png]]
|
||||
|
||||
*** Méthode 4
|
||||
**** Taille des formes non contrôlée
|
||||
#+CAPTION: Image générée à partir de ~img/mahakala-monochrome.png~ avec 2000 améliorations avec la quatrième méthode sans l’option ~-s~
|
||||
[[./output4-1.png]]
|
||||
**** Taille des formes contrôlée
|
||||
#+CAPTION: Image générée à partir de ~img/mahakala-monochrome.png~ avec 2000 améliorations avec la quatrième méthode avec l’option ~-s~
|
||||
[[./output4-2.png]]
|
||||
|
Binary file not shown.
16
src/main.cc
16
src/main.cc
@ -8,8 +8,10 @@
|
||||
int main(int ac, char** av)
|
||||
{
|
||||
std::srand(std::time(nullptr));
|
||||
auto const [input_file, output_file, iterations, method, verbose]
|
||||
= parse_args(ac, av);
|
||||
auto const [input_file, output_file, iterations, method, division,
|
||||
controlled_size, verbose
|
||||
|
||||
] = parse_args(ac, av);
|
||||
spdlog::set_level(verbose ? spdlog::level::debug : spdlog::level::info);
|
||||
spdlog::debug("Input file:\t{}", input_file.native());
|
||||
spdlog::debug("Output file:\t{}", output_file.native());
|
||||
@ -29,12 +31,12 @@ int main(int ac, char** av)
|
||||
method3(input_image, process_image, iterations);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
method4(input_image, process_image, iterations);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
method4(input_image, process_image, iterations, controlled_size);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
spdlog::error("Requested method {} is not implemented.");
|
||||
spdlog::error("Requested method {} is not implemented.", method);
|
||||
std::exit(-1);
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,10 @@ void method3(cv::Mat const& t_reference, cv::Mat& t_output, int t_iterations)
|
||||
}
|
||||
}
|
||||
|
||||
void method4(cv::Mat const& t_reference, cv::Mat& t_output, int t_iterations)
|
||||
void method4(cv::Mat const& t_reference,
|
||||
cv::Mat& t_output,
|
||||
int t_iterations,
|
||||
bool controlled_size)
|
||||
{
|
||||
auto const init_iter = t_iterations;
|
||||
auto diff = euclidian_distance(t_reference, t_output);
|
||||
@ -218,27 +221,38 @@ void method4(cv::Mat const& t_reference, cv::Mat& t_output, int t_iterations)
|
||||
results{};
|
||||
std::vector<std::pair<cv::Mat, double>> values{};
|
||||
for (unsigned i = 0; i < thread_nbr; ++i) {
|
||||
results.push_back(
|
||||
std::async(std::launch::async, methods_private::createCandidate,
|
||||
std::ref(t_output), std::ref(t_reference),
|
||||
std::ref(colors), diff, true, init_iter, t_iterations));
|
||||
results.push_back(std::async(
|
||||
std::launch::async, methods_private::createCandidate,
|
||||
std::ref(t_output), std::ref(t_reference), std::ref(colors), diff,
|
||||
controlled_size, init_iter, t_iterations));
|
||||
}
|
||||
for (auto& elem : results) {
|
||||
if (auto res = elem.get(); res.has_value() && res->second < diff) {
|
||||
values.push_back(*res);
|
||||
values.push_back(*res);
|
||||
}
|
||||
}
|
||||
if(values.size() > 0) {
|
||||
unsigned best = 0;
|
||||
for(unsigned i = 0; i < values.size(); ++i) {
|
||||
if(values[i].second < values[best].second) {
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
diff = values[best].second;
|
||||
values[best].first.copyTo(t_output);
|
||||
--t_iterations;
|
||||
if (values.size() > 0) {
|
||||
unsigned best = 0;
|
||||
for (unsigned i = 0; i < values.size(); ++i) {
|
||||
if (values[i].second < values[best].second) {
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
diff = values[best].second;
|
||||
values[best].first.copyTo(t_output);
|
||||
--t_iterations;
|
||||
spdlog::debug("iteration:{} diff:{}", t_iterations, diff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void method5(cv::Mat const& t_reference,
|
||||
cv::Mat& t_output,
|
||||
int t_iterations,
|
||||
int t_nb_tiles,
|
||||
bool t_controlled_size = false)
|
||||
{
|
||||
std::vector<cv::Mat> tiles{static_cast<size_t>(t_nb_tiles * t_nb_tiles)};
|
||||
int col_width = t_reference.cols / t_nb_tiles;
|
||||
spdlog::info("collumns of {}px", col_width);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
constexpr int DEFAULT_ITERATIONS = 5000;
|
||||
constexpr int DEFAULT_ITERATIONS = 2000;
|
||||
|
||||
using path = std::filesystem::path;
|
||||
namespace po = boost::program_options;
|
||||
@ -22,16 +22,22 @@ void processFilenames(po::variables_map const& vm,
|
||||
}
|
||||
|
||||
[[nodiscard]] auto parse_args(int t_ac, char** t_av)
|
||||
-> std::tuple<path, path, int, int, bool>
|
||||
-> std::tuple<path, path, int, int, int, bool, bool>
|
||||
{
|
||||
po::options_description desc("Allowed options");
|
||||
desc.add_options()("help,h", "Display this help message")(
|
||||
"input,i", po::value<path>(), "Input image")(
|
||||
"output,o", po::value<path>(),
|
||||
"Image output path (default: input path + \"_output\")")(
|
||||
"method,m", po::value<int>(), "Method number to be used (default: 1)")(
|
||||
"iterations,n", po::value<int>(), "Number of iterations (default: 5000)")(
|
||||
"verbose,v", "Enables verbosity");
|
||||
desc.add_options()
|
||||
("help,h", "Display this help message")
|
||||
("input,i", po::value<path>(), "Input image")
|
||||
("output,o", po::value<path>(),
|
||||
"Image output path (default: \"output_\" + input path)")
|
||||
("method,m", po::value<int>(), "Method number to be used (default: 1)")
|
||||
("iterations,n", po::value<int>(), "Number of iterations (default: 2000)")
|
||||
("size,s", "Controlled size of the random shapes (default: false)")
|
||||
("division,d", po::value<int>(),
|
||||
"For method 5, number of regions the reference image should be divided "
|
||||
"into. For instance, -d4 will divide the reference image into a 4*4 "
|
||||
"matrice of smaller images. (default: 1)")
|
||||
("verbose,v", "Enables verbosity");
|
||||
po::variables_map vm;
|
||||
po::store(po::parse_command_line(t_ac, t_av, desc), vm);
|
||||
po::notify(vm);
|
||||
@ -49,5 +55,7 @@ void processFilenames(po::variables_map const& vm,
|
||||
input_path, output_path,
|
||||
vm.count("iterations") ? vm["iterations"].as<int>() : DEFAULT_ITERATIONS,
|
||||
vm.count("method") ? vm["method"].as<int>() : 1,
|
||||
vm.count("division") ? vm["division"].as<int>() : 1,
|
||||
vm.count("size") ? true : false,
|
||||
vm.count("verbose") ? true : false);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user