User Tools

Site Tools


in204:tds:sujets:td9:part1

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
in204:tds:sujets:td9:part1 [2021/11/06 10:15]
bmonsuez
in204:tds:sujets:td9:part1 [2022/11/18 10:49] (current)
Line 6: Line 6:
  
 [[http://​en.cppreference.com/​w/​cpp/​thread/​thread|std::​thread]] [[http://​en.cppreference.com/​w/​cpp/​thread/​thread|std::​thread]]
- 
- 
-====== Partie n°1 ====== 
- 
-Nous souhaitons mesurer le temps de calcul d'une fonction. Pour ce faire, nous souhaitons créer une fonction : 
-- qui va prendre en argument la fonction que nous souhaitons exécuter, 
-- les arguments que nous devons passer à cette fonction, 
-- qui va lancer un chronomètre,​ 
-- qui va lancer la fonction 
-- qui va récupérer le résultat de la fonction, 
-- qui va estimer le temps passé par le temps de la fonction, 
-- qui va retourner à la fois le  résultat de la fonction mais aussi le temps passé par la fonction. 
  
 ===== Question n°1 ===== ===== Question n°1 =====
  
-Pour simplifier la conception, écrivez dans un premier la fonction qui appelle la fonction factorielle qui suit: +Créer ​un processus léger ​qui est associé à une fonction ​simple.
-et qui va exécuter cette fonction+
  
 <code cpp> <code cpp>
-int factorial(int n)+#​include<​iostream>​ 
 +#​include<​thread>​ 
 + 
 +void simple_method()
 { {
-    return n <1 ? 1 : (n * factorial(n - 1));+ int i 5; 
 + int x = 10; 
 + int result = i * x; 
 + std::cout << "This code calculated the value " 
 + << result << " from thread ID: "  
 + << std::​this_thread:​:get_id() << "​\n"​;
 } }
-</​code>​ 
  
-La fonction aura le squelette suivant: + 
-<​code>​ +int main()
-int estimate_time(int n)+
 { {
-    // Code pour lancer le chronomètre + std::​thread simpleThread(&​simple_method);​ 
-    int result = factorial(n); + std::cout << "Main thread is executing and waiting\n"; 
-    // Code pour calculer le temps écoulé et affiché celui-ci+ simpleThread.join(); 
-    return ​result;+ std::cout << "​Alternate thread has terminated.\n"; 
 + return ​0;
 } }
 +
 </​code>​ </​code>​
  
-===== Question n°2 =====+Exécuter le code et analyser la sortie. Commenter celle-ci, notamment au regard de la documentation de la classe [[http://​en.cppreference.com/​w/​cpp/​thread/​thread|std::​thread]].
  
-Transformer la fonction précédente ​<code>estimate_time</​code>​ pour qu'​elle prenne en argument une fonction arbitraire à un argument et un résultat. ​+<hidden Correction>
  
-Il faudra penser ​à utiliser ​un modèle (template) de fonctions.+Un objet ''​std::​thread''​ correspondant ​à un processus léger est créé et est associé au code la méthode ''​simple_method''​. Ce processus démarre immédiatement et lance le calcul. L'​exécution du code principal se poursuit et le message ''​Main thread is executing and waiting''​ est affiché. La ligne suivant attend que l'​exécution du processus léger associé à l'​objet ''​std::​thread''​ termine. Une fois que ce processus a terminé, l'​exécution du processus principal continue, affiche le message ''​Alternate thread has terminated''​ et rend la main.
  
-===== Question n°3 =====+</​hidden>​
  
-Nous souhaitons désormais pouvoir prendre une fonction pouvant prendre plusieurs arguments comme la fonction puissance.+ 
 +===== Question n°2 ===== 
 + 
 +Ecrire un programme qui lance les deux calculs suivants en parallèle, le premier dans un processus léger secondaire, le premier dans le processus léger principal :
  
 <code cpp> <code cpp>
-template<​class T1, T2>  +void worker_process(int numberOfIterations)
-T1 power(T2 x, int y)+
 { {
-   T1 result ​(T1)1.0 + for (int i = 1; i < numberOfIterations;​ i++
-   ​while(y-- > 0+
-       result ​ = result * (T1)x+ std::cout << "​Worker Thread: " << ​ i << "​\n"​
-   return result;+ }
 } }
 </​code>​ </​code>​
  
-Modifier ​le code de la fonction pour pouvoir prendre une telle fonction comme paramètre.+et 
 +<code cpp> 
 +void main_process() 
 +
 + for (int i = 1; i < 1000; i++) 
 +
 + std::cout << "​Primary Thread: " << i << "​\n";​ 
 +
 +
 +</​code>​ 
 +  
 +Tester ​le code. 
 +  
 +<hidden Correction>​
  
-Estimer ​le temps nécesaire pour calculer par exemple : 1.02 ^ 10000000.+Nous pouvons écrire ​le code suivant qui crée deux processus légers, le premier exécutant la fonction ''​worker_process''​ avec comme paramètre ''​10000''​ et le second exécutant la fonction ''​main_proc''​.
  
 +<code cpp>
 +int main()
 +{
 + std::​thread worker_proc(&​worker_process,​ 10000);
 + std::​thread main_proc(&​main_process);​
 + worker_proc.join();​
 + main_proc.join();​
 +}
 +</​code>​
  
-==== Question n°5 ====+L'​exécution commence par la tâche ''​worker_proc''​ et nous devons voir certains messages de la tâche ''​main_proc'',​ nous voyons cependant que les messages ne sont pas très entrelacés,​ ce qui est du au fait que l'on alloue un temps d'​utilisation de la console à chacun des deux processus légers.
  
-Créer une fonction nouvelle qui va appeller la fonction <​code>​estimate_time</​code> ​pour calculer <​code>​x</​code>​ fois le temps et retourné ​le temps moyen pour effectuer un "​run"​ de la fonction.+Pour mettre un peu d'​entrelacement,​ nous pouvons ajouter un peu de temps entre les affichaches,​ par exemple 1ns pour le premier processus ​et 10ns pour le secondCeci nous donne le code suivant:
  
-Exécuter cette fonction pour les fonctions ​<​code>​power</codeet <code>factorial</codeprécédemment définie.+<​code ​cpp> 
 +#include<iostream> 
 +#include<thread> 
 +#​include ​<chrono>
  
-==== Question n°4 ==== 
  
-Que faut-il faire ajouter pour dire au compilateur que la fonction <​code>​factorial</​code>​ ou que la fonction <​code>​power</​code>​ peut-être exécutée au moment de l'​exécution ? 
  
-Effectuer la modification.+void worker_process(int numberOfIterations) 
 +
 + for (int i = 1; i < numberOfIterations;​ i++) 
 +
 + std::cout << "​Worker Thread: " << i << "​\n";​ 
 + std::​this_thread::​sleep_for(10ns);​ 
 +
 +}
  
-Calculer le temps pris désormais par ces fonctions.+void main_process() 
 +
 + for (int i = 1; i < 1000; i++) 
 +
 + using namespace std; 
 + std::cout << "​Primary Thread: " << i << "​\n";​ 
 + std::​this_thread::​sleep_for(1ns);​ 
 +
 +}
  
 +int main()
 +{
 + std::​thread worker_proc(&​worker_process,​ 10000);
 + std::​thread main_proc(&​main_process);​
 + worker_proc.join();​
 + main_proc.join();​
 +}
 +</​code>​
  
 +</​hidden>​
  
  
in204/tds/sujets/td9/part1.1636193704.txt.gz · Last modified: 2021/11/06 10:15 by bmonsuez