Compilation tout en un

Portrait de trax

Un ami m'a parlé du fait que faire un énorme fichier C avec tout son code pour le compiler en une fois diminuait le temps de compilation. Certes plus qu'un seul fichier à ouvrir, édition de lien plus simple, mais bon quelque peu dubitatif j'ai voulu tester :

Créons pleins de fichiers avec pleins de fonctions :

echo -e "#include \"main.h\"\nint main(){" > main.c 
for i in {1..50}; 
do 
  echo "#include <stdio.h>" > plop$i.c 
  for j in {1..100}
  do  
    echo  void "plop$i"'_'"$j(){printf(\"plop$i"'_'"$j\n\");}" >> plop$i.c 
    echo  "plop$i"'_'"$j();" >> main.c
    echo  "void plop$i"'_'"$j();" >> main.h
 
  done
done 
echo -e "return 0;\n}" >> main.c

Conditions presque réels, utilisation un Makefile :

CC = gcc
 
CFLAGS = -Wall -W  -std=gnu99
 
SRC_C =$(shell ls plop*c) main.c
OBJS = $(SRC_C:.c=.o)
EXEC = prog
 
COMPILE := $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $(EXEC)
 
debug : CFLAGS += -DDEBUG -g
 
 
all:$(EXEC)
 
$(EXEC):$(OBJS)
        $(COMPILE)
 
debug :$(OBJS)
        $(COMPILE)
 
%.o: %.c %.h
        $(CC) $(CFLAGS) -c $(<) -o $(@)
 
clean:
        -rm $(EXEC)
        -rm *.o
$ time make > /dev/null 
 
real    0m2.975s
user    0m2.160s
sys     0m0.513s

Testons la solution avec 2 fichiers (main.c + 1 fichier contenant toutes les autres fonctions) :

> mastor.c
for i in ./plop*c
do
cat $i >> mastor.c
done
gcc -Wall mastor.c main.c -o plop
$ time sh mastor.sh 
 
real    0m1.599s
user    0m1.453s
sys     0m0.090s

Damn it works ! Mais je n'ai pas dit mon dernier mot :)

make $[$(cat /proc/cpuinfo |grep processor |wc -l) +1] > /dev/null
 
real    0m1.000s
user    0m2.793s
sys     0m0.513s

Soyons fous : même chose mais avec 500 fichiers et 1000 fonctions par fichier.

make 
real    2m39.039s
user    2m24.897s
sys     0m9.799s
 
maje -j5
real    1m6.413s
user    3m53.238s
sys     0m13.166s
 
$ time sh mastor.sh 
gcc: Internal error: Segmentation fault (program cc1)
Please submit a full bug report.
See <http://bugs.gentoo.org/> for instructions.
 
real    0m7.260s
user    0m6.243s
sys     0m0.500s

Commentaires

Portrait de paul

Conclusion ?

Je n'ai pas compris ce que tu faisais pour avoir un segfault (qu'est mastor.sh) ?

Ma conclusion c'est que bien sûr de multiples fichiers à compiler en parallèle ça va plus vite qu'un seul avec un processus, mais comme il sont compilés en parallèle le compilateur ne peut faire les même optimisations qu'en les regroupant tous dans un même fichier.

Portrait de trax

Mastor.sh c'est le script qui regroupe tout les fichiers en un seul.

Justement la prédiction de départ est ce que à allait plus vite avec un gros fichier.

Après pour les optimisations il faudrait faire des benchs mais je prends les paris (1Kg de cacahuètes) que gain (si il y a) ne dépasse pas les 4.2%

2B G33K || !2B