User Tools

Site Tools


in204:tds:sujets:td9:part3

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
in204:tds:sujets:td9:part3 [2021/11/08 09:59]
bmonsuez
in204:tds:sujets:td9:part3 [2022/11/18 10:49] (current)
Line 1: Line 1:
-====== ​Partie 3 : Exécution ​à la compilation ​======+====== Exécution ​asynchrone ​======
  
 [[in204:​tds:​sujets:​td9|TD9]] [[in204:​tds:​sujets:​td9|TD9]]
Line 5: Line 5:
 ===== Références===== ===== Références=====
  
 +[[http://​en.cppreference.com/​w/​cpp/​thread/​async|std::​async]] [[http://​en.cppreference.com/​w/​cpp/​thread/​future|std::​future]]
  
-===== Question ​1 : =====+===== Question ​n°1 =====
  
-Nous nous intéressons à l'​estimation du temps de calcul des fonction ​''​factorial''​ et des fonctions ''​power_by_int''​ que nous avons défini précédemment.+Nous considérons la fonction ​suivante qui calcule les décimales de « e ». 
 +<code cpp> 
 +std::string computeE(int numberOfDigits) 
 +
 + int sizeOfTable = numberOfDigits + 9; 
 + int* table = (int*)_alloca(sizeOfTable * sizeof(numberOfDigits));​ 
 + table[0] = 0; 
 + table[1] = 2; 
 + for (int i = sizeOfTable - 1; i > 0; i--) { 
 + table[i] = 1; 
 + }
  
-<code cpp> + std::​ostringstream output; 
-    auto fn  ​estimate_function_time(factorial, 100)+ int x 0; 
-    ​std::​cout << "​Computing fact(100)=" << fn .second << " in " << fn.first.count() << " ticks.\n"​+ table[1] = 2; 
-    auto pw estimate_function_time(power_by_int<​long double>, ​1.0002, 1000000)+ for (; sizeOfTable > 9; sizeOfTable -- )  
-    ​std::​cout ​<< ​"​Computing 1.02^1000000="​ << pw.second << " in " << pw.first.count() << " ticks.\n"​;+
 + for (int i = sizeOfTable - 1; i > 0; i-- 
 +
 + table[i] ​x % i
 + 10 * table[i - 1] + x / i
 +
 + output ​<< ​x; 
 +
 + return output.str(); 
 +}
 </​code>​ </​code>​
  
-Ceci nous retourne le temps mis pour calculer ​la fonction ​''​factorial'' ​et pour la fonction ''​power_by_int''​.+Implanter ​la fonction et vérifier que celle-ci fonctionne correctement.
  
-Expérimenter.+<hidden Correction>​
  
-===== Question 2 : =====+<code cpp> 
 +#​include<​sstream>​ 
 +#​include<​iostream>​
  
 +std::string computeE(int numberOfDigits)
 +{
 + int sizeOfTable = numberOfDigits + 9;
 + int* table = (int*)_alloca(sizeOfTable * sizeof(numberOfDigits));​
 + table[0] = 0;
 + table[1] = 2;
 + for (int i = sizeOfTable - 1; i > 0; i--) {
 + table[i] = 1;
 + }
  
-Nous souvaitons indiquer au compilateur qu'il peut calculer au moment de la compilation les expressions si celles-ci sont constantes. + std::​ostringstream output; 
- + int x = 0; 
-Pour ce faire nous ajoutons le mot-clé ''​constexpr''​ devant la fonction ou l'​expression dont la valeur peut-être exécuté au moment de la compilation. + table[1] = 2; 
- + for (; sizeOfTable > 9; sizeOfTable--) 
-Ainsi, nous pouvons indiquer que les deux fonctions ''​factorial''​ et ''​power_by_int''​ peuvent être calculer au moment de la compilation si les arguments sont des valeurs définies au moment de la compilation. + { 
- + for (int i = sizeOfTable - 1; i > 0; i--
-<code cpp> +
-constexpr long double factorial(int n+ table[i] ​x % i; 
-+10 table[i ​- 1] + x / i; 
- return n == 0 ? 1 : n factorial(n ​- 1);+
 + output << x; 
 +
 + return output.str();
 } }
  
-template<​class numericalT>​ +int main()
-constexpr numericalT power_by_int(numericalT x, int y)+
 { {
- numericalT result ​= (numericalT)1.0+ std::string value computeE(100); 
- while (y-- > 0) + std::cout << "e with " << 100 << " decimals\n"​ << value << std::endl;
- result *= x; +
- return result;+
 } }
 </​code>​ </​code>​
 +</​hidden>​
 +===== Question n°2 =====
  
-Ceci autorise le compilateur a compilé ​l'​expression au moment ​de la compilation.+Nous constatons que calculer 10000 ou 20000 décimales de e, cela prend du temps. Nous souhaitons transformer cela en une fonction asynchrone à l’aide ​de la fonction [[http://​en.cppreference.com/​w/​cpp/​thread/​async|std::​async]].
  
 +Ecrire le code transformant la précédente fonction en une fonction asynchrone en utilisant la fonction [[http://​en.cppreference.com/​w/​cpp/​thread/​async|std::​async]].
  
-===== Question 1 =====+Au lieu d'​appeller directement la fonction ​ ''​computeE'',​ nous appellons la fonction ''​computeE''​ au travers d'un appel à la fonction ''​std::​async''​ qui va exécuter la fonction ''​computeE''​ de manière asynchone et retourner un objet de type ''​std::​future<​string>''​ qui va permettre de savoir si le résultat et disponible et aussi d'​avoir la valeur du résultat quand celui-ci sera disponible.
  
-Tester le code suivant: 
  
 +<hidden Correction>​
 <code cpp> <code cpp>
 +void display(std::​future<​std::​string>&​ aFutureValue,​ int theDecimals)
 +{
 + aFutureValue.wait();​
 + std::cout << "e with " << theDecimals << " decimals\n"​ << aFutureValue.get() << std::endl;
 +}
  
-auto fn = estimate_function_time(factorial, 100); +int main() 
-std::cout << "​Computing fact(100)=" << fn.second << " in " << fn.first.count() << " ticks.\n";​ +{ 
-fn = estimate_function_time([]() { return factorial(100);​ }); + std::future<std::​string>​ eWidth20000 ​std::async(std::launch::​async&​computeE20000); 
-std::cout << "​Computing fact(100)="​ << fn.second << " in " << fn.first.count() << " ticks.\n";​ + std::future<std::​string>​ eWidth100000 ​std::async(std::​launch::​async,​ &​computeE,​ 100000); 
- + display(eWidth20000,​ 20000); 
-auto pw = estimate_function_time(power_by_int<​long double>1.00021000000); + display(eWidth100000,​ 100000); 
-std::cout << "​Computing 1.02^1000000=" << pw.second << " in " << pw.first.count() << " ticks.\n"​+}
-pw = estimate_function_time([]() { return factorial(100);​ }); +
-std::cout << "​Computing 1.02^1000000="​ << pw.second << " in " << pw.first.count() << " ticks.\n"​+
 </​code>​ </​code>​
- +</​hidden>​
-Expliquer pourquoi nous avons de telles différences entre les différentes exécutions ? +
- +
-===== Question 2 : ===== +
- +
-Tester le code suivant:+
  
  
 +=====  Question n°3 ===== 
  
 +Lancer deux calculs asynchrones,​ l’un calculant les 1000 premières décimales, l’autre les 10000 premières décimales et afficher les résultats dès que ceux-ci sont disponibles.
  
 +<hidden Correction>​
 +La fonction ''​main''​ précédente effectue déjà ce calcul.
 +</​hidden>​
  
  
in204/tds/sujets/td9/part3.1636365584.txt.gz · Last modified: 2021/11/08 09:59 by bmonsuez