updated benchmark script and beginning method 5

This commit is contained in:
Phuntsok Drak-pa 2019-04-09 02:20:33 +02:00
parent 41cbb90213
commit 4201e5476e
12 changed files with 174 additions and 90 deletions

View File

@ -23,6 +23,8 @@ enable_cxx_compiler_flag_if_supported("-Wpedantic")
enable_cxx_compiler_flag_if_supported("-pedantic") enable_cxx_compiler_flag_if_supported("-pedantic")
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
enable_cxx_compiler_flag_if_supported("-g") enable_cxx_compiler_flag_if_supported("-g")
enable_cxx_compiler_flag_if_supported("-pg")
enable_cxx_compiler_flag_if_supported("-finstrument-functions")
else() else()
enable_cxx_compiler_flag_if_supported("-O3") enable_cxx_compiler_flag_if_supported("-O3")
enable_cxx_compiler_flag_if_supported("-flto") enable_cxx_compiler_flag_if_supported("-flto")

View File

@ -1,20 +1,29 @@
#!/usr/bin/env fish #!/usr/bin/env fish
# This script was written to work with the fish shell. If you do not have the # 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 # fish shell installed on your system, please install it before executing this
# script. # script.
# The results will be stored in the output file `results.txt` # The results will be stored in the output file `results.txt`
set nb_amelioration 10 50 100 200 500 1000 set nb_amelioration 10 50 100 200 500 1000
set nb_execution 200 100 50 20 10 5 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 set output results.txt
rm -f $output rm -f $output
for method in $available_methods for method in $available_methods
for i in (seq (count $nb_execution)) set nb_options (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 "Method $method:" >> $output
echo "" >> $output echo "| / | < | < |" >> $output
echo "| Nb daméliorations | Nb dexécutions | Temps dexé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 end
echo "" >> $output
end end

View File

@ -43,6 +43,8 @@ void method2(cv::Mat const&, cv::Mat&, int);
void method3(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_ */ #endif /* GENETIC_IMAGE_INCLUDE_GENIMG_METHODS_HH_ */

View File

@ -4,7 +4,7 @@
#include <filesystem> #include <filesystem>
#include <tuple> #include <tuple>
[[nodiscard]] auto parse_args(int, char**) [[nodiscard]] auto parse_args(int, char**) -> std::
-> std::tuple<std::filesystem::path, std::filesystem::path, int, int, bool>; tuple<std::filesystem::path, std::filesystem::path, int, int, int, bool, bool>;
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_PARSEARGS_HH_ */ #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

View File

@ -39,10 +39,10 @@ $$\sqrt{\sum_{i=0}^n(v_i - w_i)^2}$$
~V~ étant le vecteur de pixels de limage de référence, ~W~ étant le vecteur de ~V~ étant le vecteur de pixels de limage de référence, ~W~ étant le vecteur de
pixels de limage générée, et ~n~ la taille de ces deux vecteurs. pixels de limage 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 dun processeur Les tests de temps sont réalisés sur un Lenovo Ideapad Y700, disposant dun
Intel® Core™ i5-2540M à 2.6GHz, composé de deux cœurs supportant chacun deux processeur Intel® Core™ i7-6700HQ à 2.6GHz et un turbo à 3.5GHz, composé de
threads, et de 4Go de RAM. Le programme est compilé avec les options quatre cœurs supportant chacun deux threads, et de 16Go de RAM. Le programme est
doptimisation ~-O3~ et ~-flto~. compilé avec les options doptimisation ~-O3~ et ~-flto~.
Voici également ci-dessous la liste des options et arguments possibles Voici également ci-dessous la liste des options et arguments possibles
concernant lexécution du logiciel. concernant lexécution du logiciel.
@ -57,21 +57,12 @@ concernant lexécution du logiciel.
-v [ --verbose ] Enables verbosity -v [ --verbose ] Enables verbosity
#+end_src #+end_src
Voici la ligne de commande utilisée depuis le répertoire ~build~ afin de pouvoir Voici le script grâce auquel les valeurs de temps dexécution ont été obtenues :
obtenir un temps dexé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
Les deux éléments entre accolades sont à remplacer par leur valeur, par exemple #+INCLUDE: ../benchmarks.fish src shell -n
afin dexécuter dix fois le programme avec vingt améliorations, il faudrait
exécuter ceci : Quelques-unes de ces lignes commençasont là uniquement pour de la mise en forme des
#+begin_src shell données afin que je puisse
perf stat -r 1 -B ./bin/genetic-image \
-i ../img/mahakala-monochrome.jpg -o output.png -n 20 -m 1
#+end_src
** Méthode naïve ** Méthode naïve
@ -86,15 +77,15 @@ de référence.
Voici les moyennes de temps dexécution selon le nombre ditérations réussies Voici les moyennes de temps dexécution selon le nombre ditérations réussies
sur le nombre dexécutions indiqué. sur le nombre dexécutions indiqué.
| / | < | < | < | | / | < | < |
| Nb daméliorations | Temps dexécution (s) | Variation (s) | Nb dexécutions | | Nb daméliorations | Nb dexécutions | Temps dexécution (s) |
|--------------------+-----------------------+---------------+-----------------| |--------------------+-----------------+-----------------------|
| 10 | 0.060847 | 0.000498 | 200 | | 10 | 200 | 0.065881 |
| 50 | 0.29823 | 0.00453 | 100 | | 50 | 100 | 0.130041 |
| 100 | 0.7093 | 0.0135 | 50 | | 100 | 50 | 0.186012 |
| 200 | 1.9584 | 0.0559 | 20 | | 200 | 20 | 0.385982 |
| 500 | 8.739 | 0.291 | 10 | | 500 | 10 | 1.437486 |
| 1000 | 27.930 | 0.582 | 5 | | 1000 | 5 | 3.608983 |
Naturellement, la variation en temps dexécution croît en même temps que le Naturellement, la variation en temps dexécution croît en même temps que le
nombre daméliorations nécessaires à apporter à limage à améliorer, dû à la nombre daméliorations nécessaires à apporter à limage à améliorer, dû à la
@ -120,17 +111,17 @@ de rapidité à lexécution. Cette méthode est celle implémentée dans la f
Voici les moyennes de temps dexécution selon le nombre ditérations réussies Voici les moyennes de temps dexécution selon le nombre ditérations réussies
sur le nombre dexécutions indiqué. sur le nombre dexécutions indiqué.
| / | < | < | < | | / | < | < |
| Nb daméliorations | Temps dexécution (s) | Variation (s) | Nb dexécutions | | Nb daméliorations | Nb dexécutions | Temps dexécution (s) |
|--------------------+-----------------------+---------------+-----------------| |--------------------+-----------------+-----------------------|
| 10 | 0.074951 | 0.000533 | 200 | | 10 | 200 | 0.072979 |
| 50 | 0.26385 | 0.00401 | 100 | | 50 | 100 | 0.114426 |
| 100 | 0.6385 | 0.0148 | 50 | | 100 | 50 | 0.157965 |
| 200 | 1.6145 | 0.0348 | 20 | | 200 | 20 | 0.290475 |
| 500 | 6.747 | 0.235 | 10 | | 500 | 10 | 0.785426 |
| 1000 | 19.608 | 0.327 | 5 | | 1000 | 5 | 2.664046 |
On peut remarquer une amélioration dans la rapidité dexécution du logiciel. On peut remarquer une amélioration quant à la rapidité dexécution du logiciel.
Cependant, le résultat nest pas aussi important quescompté. Je suppose que Cependant, le résultat nest pas aussi important quescompté. Je suppose que
cela est dû au fait que lalgorithme précédent peut considérer un rapprochement cela est dû au fait que lalgorithme précédent peut considérer un rapprochement
dune zone déjà colorée vers la couleur dorigine comme une amélioration, avec dune zone déjà colorée vers la couleur dorigine comme une amélioration, avec
@ -164,15 +155,15 @@ $$taille=Rand([\![tailleMinimale;tailleMaximale[\![)$$
Voici les moyennes de temps dexécution selon le nombre ditérations réussies Voici les moyennes de temps dexécution selon le nombre ditérations réussies
sur le nombre dexécutions indiqué. sur le nombre dexécutions indiqué.
| / | < | < | < | | / | < | < |
| Nb daméliorations | Temps dexécution (s) | Variation (s) | Nb dexécutions | | Nb daméliorations | Nb dexécutions | Temps dexécution (s) |
|--------------------+-----------------------+---------------+-----------------| |--------------------+-----------------+-----------------------|
| 10 | | | 200 | | 10 | 200 | 0.082068 |
| 50 | | | 100 | | 50 | 100 | 0.244236 |
| 100 | | | 50 | | 100 | 50 | 0.418075 |
| 200 | | | 20 | | 200 | 20 | 1.453703 |
| 500 | | | 10 | | 500 | 10 | 4.777205 |
| 1000 | | | 5 | | 1000 | 5 | 20.33209 |
Cette version du logiciel est nettement plus lente que ses versions précédentes 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 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 générée, celle avec le meilleur score est conservée. Cela permet ainsi de
multiplier les chances davoir une amélioration de limage par tentative. multiplier les chances davoir une amélioration de limage par tentative.
Voici les benchmarks dexécution de cette méthode sans contrôle de la taille des
formes aléatoires :
| / | < | < |
| Nb daméliorations | Nb dexécutions | Temps dexé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 dexécution de cette même méthode avec contrôle de la
taille des formes aléatoires :
| / | < | < |
| Nb daméliorations | Nb dexécutions | Temps dexé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 dexécution sest nettement
amélioré, avec un temps dexécution à peu près deux fois plus rapide pour
lexé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
dessayer de mettre en concurrence plusieurs threads, il serait possible
dessayer de plutôt les mettre en collaboration. Cela implique par exemple de
diviser limage dentrée en plusieurs zones sur laquelle chacun des threads
lancés travailleraient, appliquant chacun le nombre damé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 * Annexes
** Images ** 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 *** 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 #+CAPTION: Image générée à partir de ~img/mahakala-monochrome.png~ avec 2000 améliorations avec la première méthode
[[./output1.png]] [[./output1.png]]
*** Méthode 2 *** Méthode 2
#+CAPTION: Image générée à partir de ~img/mahakala-monochrome.png~ avec 2000 améliorations avec la seconde méthode #+CAPTION: Image générée à partir de ~img/mahakala-monochrome.png~ avec 2000 améliorations avec la seconde méthode
[[./output2.png]] [[./output2.png]]
*** Méthode 3 *** 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 #+CAPTION: Image générée à partir de ~img/mahakala-monochrome.png~ avec 2000 améliorations avec la troisième méthode
[[./output3.png]] [[./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 loption ~-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 loption ~-s~
[[./output4-2.png]]

Binary file not shown.

View File

@ -8,8 +8,10 @@
int main(int ac, char** av) int main(int ac, char** av)
{ {
std::srand(std::time(nullptr)); std::srand(std::time(nullptr));
auto const [input_file, output_file, iterations, method, verbose] auto const [input_file, output_file, iterations, method, division,
= parse_args(ac, av); controlled_size, verbose
] = parse_args(ac, av);
spdlog::set_level(verbose ? spdlog::level::debug : spdlog::level::info); spdlog::set_level(verbose ? spdlog::level::debug : spdlog::level::info);
spdlog::debug("Input file:\t{}", input_file.native()); spdlog::debug("Input file:\t{}", input_file.native());
spdlog::debug("Output file:\t{}", output_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); method3(input_image, process_image, iterations);
break; break;
} }
case 4: { case 4: {
method4(input_image, process_image, iterations); method4(input_image, process_image, iterations, controlled_size);
break; break;
} }
default: default:
spdlog::error("Requested method {} is not implemented."); spdlog::error("Requested method {} is not implemented.", method);
std::exit(-1); std::exit(-1);
} }

View File

@ -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 const init_iter = t_iterations;
auto diff = euclidian_distance(t_reference, t_output); 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{}; results{};
std::vector<std::pair<cv::Mat, double>> values{}; std::vector<std::pair<cv::Mat, double>> values{};
for (unsigned i = 0; i < thread_nbr; ++i) { for (unsigned i = 0; i < thread_nbr; ++i) {
results.push_back( results.push_back(std::async(
std::async(std::launch::async, methods_private::createCandidate, std::launch::async, methods_private::createCandidate,
std::ref(t_output), std::ref(t_reference), std::ref(t_output), std::ref(t_reference), std::ref(colors), diff,
std::ref(colors), diff, true, init_iter, t_iterations)); controlled_size, init_iter, t_iterations));
} }
for (auto& elem : results) { for (auto& elem : results) {
if (auto res = elem.get(); res.has_value() && res->second < diff) { if (auto res = elem.get(); res.has_value() && res->second < diff) {
values.push_back(*res); values.push_back(*res);
} }
} }
if(values.size() > 0) { if (values.size() > 0) {
unsigned best = 0; unsigned best = 0;
for(unsigned i = 0; i < values.size(); ++i) { for (unsigned i = 0; i < values.size(); ++i) {
if(values[i].second < values[best].second) { if (values[i].second < values[best].second) {
best = i; best = i;
} }
} }
diff = values[best].second; diff = values[best].second;
values[best].first.copyTo(t_output); values[best].first.copyTo(t_output);
--t_iterations; --t_iterations;
spdlog::debug("iteration:{} diff:{}", t_iterations, diff); 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);
}

View File

@ -3,7 +3,7 @@
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
constexpr int DEFAULT_ITERATIONS = 5000; constexpr int DEFAULT_ITERATIONS = 2000;
using path = std::filesystem::path; using path = std::filesystem::path;
namespace po = boost::program_options; 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) [[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"); po::options_description desc("Allowed options");
desc.add_options()("help,h", "Display this help message")( desc.add_options()
"input,i", po::value<path>(), "Input image")( ("help,h", "Display this help message")
"output,o", po::value<path>(), ("input,i", po::value<path>(), "Input image")
"Image output path (default: input path + \"_output\")")( ("output,o", po::value<path>(),
"method,m", po::value<int>(), "Method number to be used (default: 1)")( "Image output path (default: \"output_\" + input path)")
"iterations,n", po::value<int>(), "Number of iterations (default: 5000)")( ("method,m", po::value<int>(), "Method number to be used (default: 1)")
"verbose,v", "Enables verbosity"); ("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::variables_map vm;
po::store(po::parse_command_line(t_ac, t_av, desc), vm); po::store(po::parse_command_line(t_ac, t_av, desc), vm);
po::notify(vm); po::notify(vm);
@ -49,5 +55,7 @@ void processFilenames(po::variables_map const& vm,
input_path, output_path, input_path, output_path,
vm.count("iterations") ? vm["iterations"].as<int>() : DEFAULT_ITERATIONS, vm.count("iterations") ? vm["iterations"].as<int>() : DEFAULT_ITERATIONS,
vm.count("method") ? vm["method"].as<int>() : 1, 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); vm.count("verbose") ? true : false);
} }