forked from menault/2026_TD1_DEV51_Qualite_Algo
Organise le dépôt et numérote les profils par étape
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
# Exécutables, rapports et profils produits localement.
|
||||
/build/
|
||||
/out/
|
||||
/analyseur
|
||||
/rapport.txt
|
||||
/gmon.out
|
||||
*.o
|
||||
+25
-11
@@ -30,8 +30,10 @@ Le profil initial conduit aux priorités suivantes, classées par gain attendu :
|
||||
## 3. Optimisations et gains mesurés
|
||||
|
||||
Chaque gain est relatif à la version précédente. Les deux premières étapes
|
||||
reposent sur une mesure ponctuelle ; les suivantes utilisent la médiane de
|
||||
cinq exécutions par version.
|
||||
reposent sur une mesure ponctuelle ; les étapes 03 à 05 utilisent la médiane
|
||||
de cinq exécutions par version, les étapes 06 et 07 celle de dix exécutions,
|
||||
et la normalisation celle de cinquante exécutions. Chaque comparaison est
|
||||
faite sur la même machine ; les conditions peuvent varier entre les étapes.
|
||||
|
||||
| Optimisation | Modification | Avant | Après | Temps gagné |
|
||||
| --- | --- | ---: | ---: | ---: |
|
||||
@@ -40,29 +42,41 @@ cinq exécutions par version.
|
||||
| Table de hachage | Recherche et insertion en O(1) en moyenne | 0,888 s | 0,831 s | 6,4 % |
|
||||
| Longueurs et chaînes | Champ `taille`, arrêt sur `\0`, position de fin conservée | 0,832 s | 0,362 s | 56,5 % |
|
||||
| Tri par tas | Tri en O(n log n), sans tableau supplémentaire | 0,367 s | 0,113 s | 69,3 % |
|
||||
| Bigrammes | Deux lettres précédentes conservées, aucun appel à `est_lettre` | 0,1252 s | 0,1123 s | 10,3 % |
|
||||
| Mots vides | Filtre par longueur et index de hachage séparé | 0,1007 s | 0,0543 s | 46,1 % |
|
||||
| Normalisation | Table de conversion des octets, comparaison sur le même PC | 0,0569 s | 0,0508 s | 10,7 % |
|
||||
|
||||
La version finale utilise le hachage à la place de la dichotomie. Son gain
|
||||
Le programme utilise le hachage à la place de la dichotomie. Son gain
|
||||
supplémentaire reste limité car la recherche était déjà efficace.
|
||||
|
||||
Tous les appels à `longueur` sont supprimés. Le tri ne fait plus que
|
||||
**129 602 appels à `doit_echanger`**, soit environ **133 fois moins**.
|
||||
Le classement reste par fréquence décroissante, puis par ordre alphabétique.
|
||||
|
||||
La recherche des mots vides passe de **12 045 671 à 202 444 appels à
|
||||
`egales`**. Les appels à `est_lettre` et `en_minuscule` sont supprimés.
|
||||
Le gain de normalisation a été confirmé sur `salle235-06` : la nouvelle
|
||||
version est plus rapide dans les 50 paires de mesures, en temps réel et CPU.
|
||||
|
||||
## 4. Bilan et validation
|
||||
|
||||
Une comparaison directe des versions initiale et finale donne les médianes
|
||||
suivantes, sur cinq exécutions par version dans les mêmes conditions :
|
||||
Le bilan global ci-dessous a été mesuré après le tri par tas (étape 05),
|
||||
sur cinq exécutions par version dans les mêmes conditions. Les gains des
|
||||
étapes suivantes sont mesurés séparément dans le tableau précédent.
|
||||
|
||||
| Mesure | Version initiale | Version finale |
|
||||
| Mesure | Version initiale | Après le tri par tas |
|
||||
| --- | ---: | ---: |
|
||||
| Temps réel | 2,81 s | 0,11 s |
|
||||
| Pic mémoire résident (RSS) | 6 664 Kio | 6 668 Kio |
|
||||
|
||||
Le programme est environ **25,5 fois plus rapide**, soit **96,1 % de temps
|
||||
en moins** sur ce jeu de données.
|
||||
Après le tri par tas, le programme est environ **25,5 fois plus rapide**,
|
||||
soit **96,1 % de temps en moins** sur ce jeu de données.
|
||||
|
||||
Le rapport et la sortie console sont identiques octet par octet.
|
||||
L'empreinte reste **`1d53de903efd2b7c`**.
|
||||
L'empreinte reste **`1d53de903efd2b7c`**.
|
||||
|
||||
Sources : [notes](notes.md), [profil initial](out/profil_avant.txt),
|
||||
[profil final](out/profil_apres_tri.txt) et [mesures globales](out/mesures_bilan.csv).
|
||||
Sources : [notes](docs/notes.md), [ordre des profils](resultats/README.md),
|
||||
[profil initial](resultats/profils/00_initial.txt),
|
||||
[profil actuel](resultats/profils/08_normalisation.txt),
|
||||
[mesures du bilan après tri](resultats/mesures/mesures_bilan_tri.csv) et
|
||||
[comparaison de normalisation](resultats/mesures/comparaison_normalisation_meme_pc.csv).
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
CC = gcc
|
||||
CFLAGS ?= -std=c11 -Wall -Wextra -Wpedantic -O0
|
||||
|
||||
SOURCE = src/analyseur.c
|
||||
PROGRAMME = build/analyseur
|
||||
PROGRAMME_PROFIL = build/profil/analyseur
|
||||
|
||||
.PHONY: all run check profile clean
|
||||
|
||||
all: $(PROGRAMME)
|
||||
|
||||
$(PROGRAMME): $(SOURCE) Makefile
|
||||
mkdir -p $(@D)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $< -o $@ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
run: $(PROGRAMME)
|
||||
cd build && ./analyseur
|
||||
|
||||
check: run
|
||||
cmp resultats/rapport_reference.txt build/rapport.txt
|
||||
|
||||
$(PROGRAMME_PROFIL): $(SOURCE) Makefile
|
||||
mkdir -p $(@D)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -pg $< -o $@ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
profile: $(PROGRAMME_PROFIL)
|
||||
cd build/profil && ./analyseur
|
||||
cd build/profil && gprof -b ./analyseur gmon.out > profil.txt
|
||||
@printf 'Profil disponible dans build/profil/profil.txt\n'
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
@@ -1,45 +1,52 @@
|
||||
# TD — Consignes
|
||||
# Analyseur de fréquence de mots — TD R5.A.04
|
||||
|
||||
## Travail demandé
|
||||
Optimisation d'un analyseur C par mesure du temps, étude des profils et
|
||||
réduction du travail répété. Le rapport doit conserver l'empreinte
|
||||
**`1d53de903efd2b7c`**.
|
||||
|
||||
1. **Mesurer**
|
||||
## Organisation
|
||||
|
||||
Compilez le programme sans `-pg`, lancez-le avec `time`, puis notez le
|
||||
temps d'exécution et l'empreinte mémoire.
|
||||
```text
|
||||
src/analyseur.c Programme principal
|
||||
exemples/exemple.c Exemple de profiling fourni
|
||||
docs/CONSIGNES.md Consignes originales du TD
|
||||
docs/R5A04_Profiling_MM.pdf Support du cours
|
||||
docs/notes.md Journal détaillé des mesures
|
||||
resultats/profils/ Profils historiques numérotés de 00 à 08
|
||||
resultats/mesures/ Mesures brutes CSV et conditions des expériences
|
||||
resultats/rapport_reference.txt Rapport attendu
|
||||
COMPTE_RENDU.md Compte rendu noté
|
||||
build/ Fichiers générés localement, ignorés par Git
|
||||
```
|
||||
|
||||
2. **Profiler**
|
||||
## Compiler et vérifier
|
||||
|
||||
Recompilez en `-O0` avec `-pg`, lancez le programme, puis générez le
|
||||
profil dans `profil_avant.txt` avec `gprof`.
|
||||
GCC, GNU Make et `gprof` sont nécessaires pour les commandes de profiling.
|
||||
Depuis la racine du dépôt :
|
||||
|
||||
3. **Analyser**
|
||||
```bash
|
||||
make # Compiler en -O0, sans instrumentation
|
||||
make run # Exécuter ; le rapport est écrit dans build/rapport.txt
|
||||
make check # Exécuter et comparer le rapport à la référence
|
||||
make profile # Produire build/profil/profil.txt avec -pg et gprof
|
||||
make clean # Supprimer les fichiers générés de build/
|
||||
```
|
||||
|
||||
Étudiez le profil plat et le graphe d'appels : où le temps est-il passé,
|
||||
et pourquoi ?
|
||||
Pour mesurer le temps du programme après compilation :
|
||||
|
||||
4. **Proposer**
|
||||
```bash
|
||||
cd build
|
||||
time ./analyseur
|
||||
```
|
||||
|
||||
Listez les pistes d'amélioration, classées par gain attendu.
|
||||
Les mesures de temps utilisent le binaire sans `-pg`. Les profils archivés
|
||||
dans `resultats/` sont les résultats des différentes étapes ; `make profile`
|
||||
écrit le nouveau profil dans `build/profil/`.
|
||||
|
||||
5. **Optimiser**
|
||||
## Documents et résultats
|
||||
|
||||
Réalisez une optimisation par commit. L'empreinte mémoire doit rester
|
||||
identique.
|
||||
|
||||
6. **Valider**
|
||||
|
||||
Reprofilez le programme dans `profil_apres.txt` et chiffrez le gain
|
||||
obtenu.
|
||||
|
||||
## Compte rendu noté
|
||||
|
||||
Le fichier `COMPTE_RENDU.md` doit être présent à la racine de votre fork.
|
||||
Il doit contenir :
|
||||
|
||||
- les temps avant et après optimisation ;
|
||||
- l'analyse du profil ;
|
||||
- les pistes d'amélioration proposées ;
|
||||
- les optimisations réalisées ;
|
||||
- les gains mesurés.
|
||||
|
||||
> **Contrôle continu** — Le compte rendu est évalué dans le cadre du TD.
|
||||
- [Compte rendu](COMPTE_RENDU.md)
|
||||
- [Consignes du TD](docs/CONSIGNES.md) et [support PDF](docs/R5A04_Profiling_MM.pdf)
|
||||
- [Journal des mesures](docs/notes.md)
|
||||
- [Ordre des profils et expériences](resultats/README.md)
|
||||
- [Comparaison de la normalisation sur le même PC](resultats/mesures/comparaison_normalisation_meme_pc.csv)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# TD — Consignes
|
||||
|
||||
## Travail demandé
|
||||
|
||||
1. **Mesurer**
|
||||
|
||||
Compilez le programme sans `-pg`, lancez-le avec `time`, puis notez le
|
||||
temps d'exécution et l'empreinte mémoire.
|
||||
|
||||
2. **Profiler**
|
||||
|
||||
Recompilez en `-O0` avec `-pg`, lancez le programme, puis générez le
|
||||
profil dans `profil_avant.txt` avec `gprof`.
|
||||
|
||||
3. **Analyser**
|
||||
|
||||
Étudiez le profil plat et le graphe d'appels : où le temps est-il passé,
|
||||
et pourquoi ?
|
||||
|
||||
4. **Proposer**
|
||||
|
||||
Listez les pistes d'amélioration, classées par gain attendu.
|
||||
|
||||
5. **Optimiser**
|
||||
|
||||
Réalisez une optimisation par commit. L'empreinte mémoire doit rester
|
||||
identique.
|
||||
|
||||
6. **Valider**
|
||||
|
||||
Reprofilez le programme dans `profil_apres.txt` et chiffrez le gain
|
||||
obtenu.
|
||||
|
||||
## Compte rendu noté
|
||||
|
||||
Le fichier `COMPTE_RENDU.md` doit être présent à la racine de votre fork.
|
||||
Il doit contenir :
|
||||
|
||||
- les temps avant et après optimisation ;
|
||||
- l'analyse du profil ;
|
||||
- les pistes d'amélioration proposées ;
|
||||
- les optimisations réalisées ;
|
||||
- les gains mesurés.
|
||||
|
||||
> **Contrôle continu** — Le compte rendu est évalué dans le cadre du TD.
|
||||
+24
-17
@@ -1,3 +1,10 @@
|
||||
# Journal des mesures et optimisations
|
||||
|
||||
Ce journal conserve les commandes et sorties historiques, avec les chemins
|
||||
utilisés au moment des mesures. Les liens vers les profils et les données
|
||||
pointent vers leur emplacement actuel. Pour compiler et exécuter le projet
|
||||
avec la nouvelle arborescence, voir le [README](../README.md).
|
||||
|
||||
Lancement du programme après la compilation avec `gcc -O0 analyseur.c -o analyseur`
|
||||
|
||||
```bash
|
||||
@@ -96,7 +103,7 @@ qu'à la première apparition de chacun des 5 866 mots distincts.
|
||||
Le tableau existant est réutilisé, sans allocation supplémentaire.
|
||||
Le tri final par fréquence produit le même classement.
|
||||
|
||||
Résultats du nouveau profil, conservé dans [out/profil_apres.txt](out/profil_apres.txt) :
|
||||
Résultats du nouveau profil, conservé dans [01_dichotomie.txt](../resultats/profils/01_dichotomie.txt) :
|
||||
|
||||
| Mesure | Avant | Après |
|
||||
| --- | ---: | ---: |
|
||||
@@ -166,9 +173,9 @@ paramètre à `ecart_type_longueur`. La boucle utilise directement cette
|
||||
valeur. Le calcul des statistiques passe ainsi de O(n²) à O(n), sans
|
||||
allocation supplémentaire ni modification de la formule de variance.
|
||||
|
||||
Profil enregistré dans [out/profil_apres_moyenne.txt](out/profil_apres_moyenne.txt).
|
||||
Profil enregistré dans [02_moyenne.txt](../resultats/profils/02_moyenne.txt).
|
||||
La colonne « Avant » correspond à la version déjà optimisée pour
|
||||
`chercher_mot`, dont le profil reste dans `out/profil_apres.txt`.
|
||||
`chercher_mot`, dont le profil reste dans `../resultats/profils/01_dichotomie.txt`.
|
||||
|
||||
| Mesure | Avant | Après |
|
||||
| --- | ---: | ---: |
|
||||
@@ -242,9 +249,9 @@ cette machine. L'index est libéré après le comptage, avant le tri final
|
||||
qui déplace les entrées. L'empreinte du rapport est conservée, mais cette
|
||||
version utilise davantage de mémoire pendant le comptage.
|
||||
|
||||
Profil enregistré dans [out/profil_apres_hachage.txt](out/profil_apres_hachage.txt).
|
||||
Profil enregistré dans [03_hachage.txt](../resultats/profils/03_hachage.txt).
|
||||
La comparaison porte sur la version précédente avec dichotomie et moyenne
|
||||
calculée une seule fois, conservée dans `out/profil_apres_moyenne.txt`.
|
||||
calculée une seule fois, conservée dans `../resultats/profils/02_moyenne.txt`.
|
||||
|
||||
| Mesure | Dichotomie | Hachage |
|
||||
| --- | ---: | ---: |
|
||||
@@ -304,9 +311,9 @@ Le champ supplémentaire fait passer `sizeof(Entree)` de 36 à 40 octets sur
|
||||
cette machine : le tableau alloué pour 20 000 entrées prend 80 000 octets
|
||||
supplémentaires, soit environ 78 Kio.
|
||||
|
||||
Profil enregistré dans [out/profil_apres_longueurs.txt](out/profil_apres_longueurs.txt).
|
||||
Profil enregistré dans [04_longueurs.txt](../resultats/profils/04_longueurs.txt).
|
||||
La version précédente, avec la table de hachage, est décrite dans
|
||||
`out/profil_apres_hachage.txt`.
|
||||
`../resultats/profils/03_hachage.txt`.
|
||||
|
||||
| Mesure | Avant | Après |
|
||||
| --- | ---: | ---: |
|
||||
@@ -384,9 +391,9 @@ supplémentaire. `doit_echanger` reste inchangée : fréquence décroissante,
|
||||
puis ordre alphabétique croissant. Chaque échange déplace l'entrée entière,
|
||||
y compris la longueur mémorisée.
|
||||
|
||||
Profil enregistré dans [out/profil_apres_tri.txt](out/profil_apres_tri.txt).
|
||||
Profil enregistré dans [05_tri.txt](../resultats/profils/05_tri.txt).
|
||||
La comparaison porte sur la version précédente, décrite dans
|
||||
`out/profil_apres_longueurs.txt`.
|
||||
`../resultats/profils/04_longueurs.txt`.
|
||||
|
||||
| Mesure | Tri à bulles | Tri par tas |
|
||||
| --- | ---: | ---: |
|
||||
@@ -464,9 +471,9 @@ restent identiques. Les deux versions sont en O(nombre de caractères) :
|
||||
le gain vient des vérifications et des appels évités, sans tableau
|
||||
supplémentaire.
|
||||
|
||||
Profil enregistré dans [out/profil_apres_bigrammes.txt](out/profil_apres_bigrammes.txt).
|
||||
Profil enregistré dans [06_bigrammes.txt](../resultats/profils/06_bigrammes.txt).
|
||||
La comparaison porte sur la version précédente, décrite dans
|
||||
`out/profil_apres_tri.txt`.
|
||||
`../resultats/profils/05_tri.txt`.
|
||||
|
||||
| Mesure | Avant | Après |
|
||||
| --- | ---: | ---: |
|
||||
@@ -533,9 +540,9 @@ doublon sont conservés pour produire exactement le même texte.
|
||||
L'index et la longueur maximale occupent 488 octets sur cette machine,
|
||||
sans allocation dynamique supplémentaire.
|
||||
|
||||
Profil enregistré dans [out/profil_apres_mots_vides.txt](out/profil_apres_mots_vides.txt).
|
||||
Profil enregistré dans [07_mots_vides.txt](../resultats/profils/07_mots_vides.txt).
|
||||
La comparaison porte sur la version précédente, décrite dans
|
||||
`out/profil_apres_bigrammes.txt`.
|
||||
`../resultats/profils/06_bigrammes.txt`.
|
||||
|
||||
| Mesure | Avant | Après |
|
||||
| --- | ---: | ---: |
|
||||
@@ -620,9 +627,9 @@ tests et sans appel de fonction pour chaque caractère.
|
||||
La table occupe 256 octets, auxquels s'ajoute l'indicateur d'initialisation
|
||||
de 4 octets sur cette machine, sans allocation dynamique.
|
||||
|
||||
Profil enregistré dans [out/profil_apres_normalisation.txt](out/profil_apres_normalisation.txt).
|
||||
Profil enregistré dans [08_normalisation.txt](../resultats/profils/08_normalisation.txt).
|
||||
La comparaison porte sur la version précédente, décrite dans
|
||||
`out/profil_apres_mots_vides.txt`.
|
||||
`../resultats/profils/07_mots_vides.txt`.
|
||||
|
||||
| Mesure | Avant | Après |
|
||||
| --- | ---: | ---: |
|
||||
@@ -687,6 +694,6 @@ sur cette machine avec `-O0`. Il représente environ 6 ms par exécution.
|
||||
Le rapport et la sortie console sont identiques sur les **110 exécutions**,
|
||||
chauffe incluse. L'empreinte reste **`1d53de903efd2b7c`**.
|
||||
|
||||
Les [100 mesures brutes](out/comparaison_normalisation_meme_pc.csv) sont
|
||||
conservées, ainsi que les [conditions et statistiques détaillées](out/comparaison_normalisation_meme_pc.json),
|
||||
Les [100 mesures brutes](../resultats/mesures/comparaison_normalisation_meme_pc.csv) sont
|
||||
conservées, ainsi que les [conditions et statistiques détaillées](../resultats/mesures/comparaison_normalisation_meme_pc.json),
|
||||
qui identifient le commit de référence et les deux sources utilisées.
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
# Résultats conservés
|
||||
|
||||
Les profils suivent l'ordre des optimisations. Les commits indiqués
|
||||
contiennent les versions de `analyseur.c` utilisées à ces étapes, avant
|
||||
le déplacement des sources dans `src/`.
|
||||
|
||||
| Étape | Profil | Version du code |
|
||||
| --- | --- | --- |
|
||||
| 00 — Programme initial | [00_initial.txt](profils/00_initial.txt) | `6c6f358` |
|
||||
| 01 — Recherche dichotomique | [01_dichotomie.txt](profils/01_dichotomie.txt) | `be387e2` |
|
||||
| 02 — Moyenne calculée une fois | [02_moyenne.txt](profils/02_moyenne.txt) | `d3f1987` |
|
||||
| 03 — Recherche par hachage | [03_hachage.txt](profils/03_hachage.txt) | `57aaec4` |
|
||||
| 04 — Longueurs et positions de fin | [04_longueurs.txt](profils/04_longueurs.txt) | `1c4405c` |
|
||||
| 05 — Tri par tas | [05_tri.txt](profils/05_tri.txt) | `57c9ce9` |
|
||||
| 06 — Analyse des bigrammes | [06_bigrammes.txt](profils/06_bigrammes.txt) | `e3076e4` |
|
||||
| 07 — Index des mots vides | [07_mots_vides.txt](profils/07_mots_vides.txt) | `1331811` |
|
||||
| 08 — Table de normalisation | [08_normalisation.txt](profils/08_normalisation.txt) | `19ad9b7` |
|
||||
|
||||
Les [mesures du bilan après le tri](mesures/mesures_bilan_tri.csv) comparent
|
||||
le programme initial à l'étape 05. La colonne `final` désigne cette étape.
|
||||
|
||||
La [comparaison de normalisation](mesures/comparaison_normalisation_meme_pc.csv)
|
||||
compare les étapes 07 et 08 sur le même PC, avec 50 mesures par version.
|
||||
Les [conditions et statistiques](mesures/comparaison_normalisation_meme_pc.json)
|
||||
précisent la machine, le compilateur, les sources et le protocole.
|
||||
|
||||
Le [rapport de référence](rapport_reference.txt) conserve l'empreinte
|
||||
`1d53de903efd2b7c`. `make check` compare le rapport courant à ce fichier.
|
||||
|
||||
Les commandes historiques et les autres mesures sont décrites dans le
|
||||
[journal](../docs/notes.md). Chaque gain de temps doit être calculé à partir
|
||||
de versions exécutées dans les mêmes conditions sur la même machine.
|
||||
@@ -14,9 +14,11 @@
|
||||
* L'empreinte affichée à la fin doit rester IDENTIQUE après optimisation :
|
||||
* elle prouve que le résultat du programme n'a pas changé.
|
||||
*
|
||||
* Compilation : gcc -O0 -pg analyseur.c -o analyseur
|
||||
* Exécution : ./analyseur
|
||||
* Profil : gprof ./analyseur gmon.out > profil.txt
|
||||
* Depuis la racine du dépôt :
|
||||
* Compilation : make
|
||||
* Exécution : make run
|
||||
* Validation : make check
|
||||
* Profil : make profile (build/profil/profil.txt)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
Reference in New Issue
Block a user