diff --git a/COMPTE_RENDU.md b/COMPTE_RENDU.md new file mode 100644 index 0000000..a2f9fbf --- /dev/null +++ b/COMPTE_RENDU.md @@ -0,0 +1,118 @@ +# Compte rendu — TD 1 : utilisation de gprof +### Nathan COUCHOT et Lucas POT + +## 1. Mesurer le programme sans instrumentation + +La mesure sans profiler se réalise avec les commandes suivantes, depuis le dossier du programme : + +```bash +gcc -O0 analyseur.c -o analyseur +time ./analyseur +``` + +La nouvelle exécution sans `-pg`, sur le même volume de texte que le profil, donne : + +| Mesure | Temps | +| --- | ---: | +| Temps réel (`real`) | 1,200 s | +| Temps CPU utilisateur (`user`) | 1,164 s | +| Temps CPU système (`sys`) | 0,022 s | + +L'empreinte du rapport est **`03c7b78f93838d02`**. Cette empreinte sert de référence pour vérifier que le résultat reste identique lors d'une comparaison effectuée avec les mêmes données. + +Les dix mots les plus fréquents sont : + +| Rang | Mot | Occurrences | +| --- | --- | ---: | +| 1 | rane | 2 811 | +| 2 | fasi | 2 399 | +| 3 | mopo | 2 161 | +| 4 | tata | 2 086 | +| 5 | vesi | 1 979 | +| 6 | laganomo | 1 784 | +| 7 | boto | 1 697 | +| 8 | nopebo | 1 653 | +| 9 | cofi | 1 612 | +| 10 | siri | 1 593 | + +## 2. Compiler avec `-pg` et produire le profil + +Pour activer l'instrumentation de `gprof`, on compile avec `-O0 -pg`, puis on exécute le programme et on génère le profil : + +```bash +gcc -O0 -pg analyseur.c -o analyseur +time ./analyseur +gprof ./analyseur gmon.out > profil_avant.txt +``` + +On passe d'une mesure de **1,200 s sans `-pg`** à un temps réel relevé de **2,750 s avec `-pg`**, soit une durée environ **2,29 fois plus longue** et un écart de **1,550 s** (environ **129 %** d'augmentation). Le profil affiche cependant seulement **0,91 s de temps effectif estimé dans les fonctions analysées**. + +L'option `-pg` ajoute du travail à chaque entrée dans une fonction pour compter les appels. Avec des dizaines de millions d'appels à de petites fonctions, ce surcoût devient très important : le profiling perturbe donc fortement la durée d'exécution. + +## 3. Analyser le profil plat et le graphe d'appels + +### Profil plat : où passe le temps ? + +Le profil plat indique le temps propre de chaque fonction, sans le temps de ses fonctions appelées. Les principaux résultats de `profil_avant.txt` sont : + +| Fonction | Part du temps propre | Temps propre affiché | Nombre d'appels | +| --- | ---: | ---: | ---: | +| `egales` | 28,02 % | 0,26 s | 121 889 737 | +| `est_mot_vide` | 13,74 % | 0,12 s | 2 500 000 | +| `analyser_bigrammes` | 12,09 % | 0,11 s | 1 | +| `decouper_lignes` | 7,69 % | 0,07 s | 1 | +| `generer_texte` | 6,59 % | 0,06 s | 1 | +| `est_lettre` | 5,49 % | 0,05 s | 52 929 320 | + +La fonction `egales` est le principal point chaud : elle compare des chaînes et représente environ 28 % du temps propre mesuré. Son coût vient surtout de son nombre d'appels, supérieur à 121 millions. + +`analyser_bigrammes`, `decouper_lignes` et `generer_texte` ne sont appelées qu'une fois, mais parcourent de grandes quantités de données. Elles peuvent donc consommer un temps significatif malgré leur faible nombre d'appels. + +### Graphe d'appels : pourquoi ces fonctions coûtent-elles du temps ? + +`main` appelle `compter_mots_ligne`, qui vérifie chaque mot avec `est_mot_vide` avant de le compter. Cette étape représente environ **51 % du temps du profil**, fonctions appelées comprises. + +Pour vérifier si un mot est vide, `est_mot_vide` le compare aux éléments d'une liste de 60 mots avec `egales`. Comme cette vérification est répétée pour les 2 500 000 mots du texte, elle entraîne plus de **120 millions de comparaisons** et représente environ **41 % du temps du profil**. + +Le principal coût vient donc de la vérification des mots vides. + +## 4. Proposer des améliorations + +Les pistes suivantes sont classées par gain attendu : + +1. **Optimiser `est_mot_vide`.** Regrouper les mots vides par longueur et première lettre éviterait de parcourir toute la liste et réduirait fortement les appels à `egales`. + +2. **Optimiser `longueur_moyenne`.** Mémoriser la longueur des mots et réutiliser la moyenne dans `ecart_type_longueur` éviterait des parcours inutiles. Le gain attendu est plus faible. + +## 5. Optimisations réalisées + +Dans `est_mot_vide`, les 60 mots vides sont regroupés une seule fois par longueur et première lettre. Pour chaque mot du texte, seules les chaînes du groupe correspondant sont comparées avec `egales`. La longueur est déjà connue lors du découpage du mot. + +La longueur de chaque mot compté est aussi mémorisée dans la table pour calculer les statistiques. La moyenne déjà calculée est transmise à `ecart_type_longueur` pour éviter de la recalculer. + +## 6. Vérifier les résultats et mesurer le gain + +Après compilation avec `gcc -O0 -pg analyseur.c -o analyseur`, deux exécutions donnent : + +| Mesure | Après : essai 1 | Après : essai 2 | +| --- | ---: | ---: | +| Temps réel | 1,200 s | 1,231 s | +| Temps CPU utilisateur | 1,147 s | 1,183 s | +| Temps CPU système | 0,016 s | 0,019 s | + +Le temps réel moyen avec `-pg` est de **1,216 s**, contre **2,750 s avant optimisation**, soit environ **55,8 % de temps en moins** et une exécution **2,26 fois plus rapide**. Cette comparaison concerne les versions instrumentées : elle inclut la réduction du surcoût de `-pg` grâce aux appels supprimés. + +La comparaison de `profil_avant.txt` et `profil_après.txt` confirme la réduction du travail : + +| Mesure du profil | Avant | Après | +| --- | ---: | ---: | +| Temps total estimé par `gprof` | 0,91 s | 0,45 s | +| Appels à `egales` | 121 889 737 | 3 413 876 | +| Temps propre de `egales` | 0,26 s | 0,02 s | +| Temps propre de `est_mot_vide` | 0,12 s | 0,02 s | +| Appels à `longueur` | 39 162 | 20 994 | +| Appels à `longueur_moyenne` | 2 | 1 | + +Les appels à `egales` diminuent d'environ **97 %**. Les 60 appels à `longueur` ajoutés par l'initialisation des groupes expliquent le passage de 20 934 appels après la seule optimisation des statistiques à 20 994 dans la version finale. + +L'empreinte reste **`03c7b78f93838d02`** dans les deux exécutions. Le Top 10 et les statistiques affichées restent identiques. \ No newline at end of file