# [compilation] optimisation pour petite RAM (résolu)

## Untux

Salut à tous,

Mon pc principal est un PIV-3GHz - 1GO RAM. Mon pc secondaire est une xbox gentoo-isée celeron 733MHz - 64MO RAM. Une compilation de glibc-2.5 sur le principal dure 55 minutes, contre 2 heures sur la xbox. Une compilation de gcc-4.1.1 sur le principal dure 50 minutes, contre... x heures sur la xbox. Ca fait plus de 18 heures que je l'ai lancée et c'est pas fini :p

Le problème c'est que, apparemment, la compilation de gcc exige beaucoup plus de mémoire que celle de glibc. Pendant le compilation gcc sur xbox, top me donne typiquement ça  :

```

Cpu(s): 0.7% us, 35.2% sy, 0.0% ni, 0.0% id, 63.8% wa, 0.3% hi, 0.0% si

Mem: 57304k total, 56036k used, 1268k free, 52k buffers

Swap:   389388k total,   157764k used,   231624k free,     1048k cached

PID   USER      PR  NI  VIRT  RES  SHR S %CPU  %MEM    TIME        COMMAND

90    root      16  0   0     0    0   D 34.9   0.0    325:06.71   kswapd0

5582  root      18  0   131m  41m  364 D  0.3  73.8     37:38.09   cc1

...

```

J'en déduit que le processeur patiente et que la swap... rame.

Alors euh... voici la question d'un ignorant qui vient vers vous les yeux pleins d'espoir (et d'illusions, je le crains) : y-a-t-il des moyens pour améliorer les temps de compilation avec une RAM rachitique ?

Pour info :

```

# /etc/make.conf

...

CFLAGS="-march=pentium3 -O2 -pipe -fomit-frame-pointer"

CHOST="i686-pc-linux-gnu"

CXXFLAGS="${CFLAGS}"

MAKEOPTS="-j1"

...

```

Merci d'avance pour vos lumières.Last edited by Untux on Thu Nov 30, 2006 11:57 am; edited 2 times in total

----------

## Oupsman

Tu as pensé à distcc en mettant ton P IV en premier dans la liste des hôtes ?

----------

## Magic Banana

Je plussoie Oupsman et en profite pour te demander pourquoi tu as fixé ton MAKEOPTS à "-j1" et non "-j2" (qui est la valeur recommendée pour les machines monoproc).

----------

## Untux

Salut les gars! Merci pour vos réponses.

J'ai essayé avec distcc. J'ai probablement survolé la doc distcc un peu trop vite, mais toujours est-il qu'après 16 heures, la compilation s'est interrompue toute seule sans que je puisse trouver de message d'erreur. Étant donné que je ne maîtrise pas encore distcc et que, selon la doc, il y a des applications qui ne le supportent pas, et qu'en plus, j'ai gcc 4 sur le principal et gcc 3 sur le secondaire, je m'étais dit que c'était peut-être distcc qui posait problème. Je l'ai donc désactivé. Sans compter que du coté du serveur principal, distccmon-gui ne me montrait aucune activité... hum, je sens que je vais devoir me replonger dans la doc distcc :s

Concernant le « -j1 » : À la première tentative j'avais « -j2 ». Vu le résultat, je m'étais dit que « -j1 » consommerait moins de mémoire. J'ai fait ça au feeling quoi :p

Bon... je vais me replonger dans la doc que je trouve sur distcc. Si ça marche toujours pas j'ouvrirai un nouveau fil [distcc].

----------

## BaNaNe

Il me semble qu'on ne peut pas mélanger les versions de GCC avec distcc. Il faut que touts les pc soient avec gcc3 ou tous avec gcc4... Ton plantage vient surement de là.

----------

## Enlight

Pour les petites ram y'a aussi les profiles basés sur uclibc au lieu de glibc.

----------

## Untux

Merci pour vos réponses. J'en suis à 24 heures de compilation là... en tout cas le disque dur bosse à donf. Le pauvre.

Suite au message de Enlight, j'ai surfé un peu pour me renseigner sur uClibc. Ça m'a l'air d'être une très bonne piste. Si je n'arrive pas à faire fonctionner distcc j'essaierai ça! Je n'ai pas trouvé de marche à suivre pour passer à uClibc. Est-ce que la marche à suivre suivante vous semble correcte ?

a) Créer un nouveau profile à partir des paramètres importants de mon profil actuel (../portage/profiles/default-linux/x86/xbox) et du profile uClibc (../portage/profiles/uclibc/x86)

b) emerge uclibc

c) faire pointer /etc/make.profile sur le nouveau profile

d) emerge world

... ça me semble un peu trop facile. J'ai oublié quelque chose ?

----------

## Enlight

J'ai vu ça vite fait, ça décrit l'installation avec profile uclibc, ça devrait te mettre sur la voie je pense.

http://gentoo-wiki.com/TinyGentoo

edit : n'ortographeLast edited by Enlight on Thu Nov 30, 2006 10:26 am; edited 1 time in total

----------

## Untux

Trop bien, merci beaucoup Enlight!

PS je détracte pas emacs. D'ailleurs, emacs c'est super pour les pieuvres.

----------

## geekounet

 *tutux wrote:*   

> PS je détracte pas emacs. D'ailleurs, emacs c'est super pour les pieuvres.

 

Haha !  :Mr. Green: 

----------

## xaviermiller

Salut,

J'utilise une alternative à distcc : monter par NFS la machine à mettre à jour dans une machine plus puissante et y chrooter.

Avantage : la machine moins puissante n'a pas besoin d'avoir l'arbre de portage, distfiles & Co, on gagne donc de la place, et on n'est pas obligés d'avoir les versions de gcc synchrones (gros avantage si on a des mix de sytèmes stable/instable)

Avec un Pentium II 266, la compil par distcc prend une semaine, contre 1 à 2 jours par NFS chrooté sur un AMD 64X2.

----------

## Untux

Ah haaaa, mais je savais pas du tout qu'on pouvait chrooter extra-muros. Merci beaucoup XavierMiller. Boudiou, GNU/Linux c'est trop beau. Pis vous vous êtes trop cool. Pour une cause que je croyais perdue, j'ai trois solutions différentes et intelligentes. J'en pleurerais...

Je crois que je vais opter pour le uClibc... pas encore sûr sûr.

Bon... après 34 heures de compilation j'étais sur le point d'envoyer un <CTRL>C dans la geule d'emerge quand soudain... là, sur l'écran... quelque chose a bougé. Ca faisait quasiment 33 heures que ce con était bloqué sur « insn-attrtab.o ». Du coup, pour le fun, j'ai décidé de laisser finir pour battre un record. C'était sans compter sur le post de XavierMiller qui me balance une compile d'une semaine... je peux pas m'aligner. Vous êtes trop forts !

----------

## anigel

Allez, juste histoire de ne pas te laisser avec "juste" 3 pistes différentes, je te propose, en complément de la solution uclibc, une "astuce" valable pour plus ou moins tous les systèmes : modifier le comportement du noyau vis-à-vis de l'utilisation de la swap, et du cache disque intégré au noyau.

"Koissa", me diras-tu ? En fait, l'idée, c'est de forcer le système à toujours utiliser prioritairement la RAM avant la swap. Autrement dit, réduire le cache disque à peau de chagrin. Parfois ça donne des résultats satisfaisants, et parfois... moins. Mais c'est à tester.

Directement en ligne de commande :

```
sysctl -w vm.swappiness=10
```

Pour conserver ce réglage ensuite :

```
echo "vm.swappiness=10" >> /etc/sysctl.conf
```

Ce réglage du noyau peut prendre une valeur de 0 à 100. Plus la valeur augmente (60 par défaut), moins le système aura tendance à "nettoyer" la RAM souvent. Plus la valeur descend, et plus le noyau sera agressif, et essaiera de libérer la mémoire pour les tâches en cours.

Bon bidouillage en tous cas !

NB : J'avais lu, il y a très longtemps, qu'il fallait éviter de mettre cette variable à 0, car ça pouvait avoir des effets bizarres. Je te préviens, j't'aurais prév'nu  :Wink: .

----------

## Untux

Ah ouais alors la swappiness elle est pas mal non plus celle là ! Adoptée et directement intégrée. Merci Anigel!

J'en profite pour vous tenir au courant : La compilation gcc4 est TERMINÉE! Après 37 heures et 15 minutes... dire que j'ai fait tout ça pour finalement passer à uClibc. lol

Merci encore à tous.

----------

## PabOu

 *tutux wrote:*   

> Concernant le « -j1 » : À la première tentative j'avais « -j2 ». Vu le résultat, je m'étais dit que « -j1 » consommerait moins de mémoire. J'ai fait ça au feeling quoi :p

 

Et c'est normal.

Le -j1 veut dire : 1 processus en simultané. -j2 veut dire : 2 processus en simultané, et ainsi de suite.

On comprend donc directement que CHAQUE processus bouffe plein de RAM (et les process de compilation, vraiment beaucoup) et que donc, pour un environnement à mémoire limitée, on évitera de saturer cette mémoire en ayant un -j trop grand.

Une petite astuce qui me vient comme ca pour libérer un petit peu de ram : couper sshd (si possible).

Une autre astuce pour les machines à faible RAM : éditer le /etc/inittab pour supprimer des terminaux (ceux qui sont accessibles par alt+touche de fonction) et commenter les lignes qui commencent par c2, c3, c4, c5 et c6. De cette façon, au reboot, tu n'auras plus qu'un seul terminal.

Tu peux aussi commenter c1 pour supprimer ce dernier terminal, mais attention en cas de bourde : si ssh n'est plus accessible : livecd pour rétablir le inittab.

----------

## Untux

Hé bin ce fil aura été riche en enseignements pour moi. Je ne regrette pas d'avoir posé la question. Merci Pabou! Pas con la suppression des consoles. C'est vrai qu'à 64MO il n'y a pas de petit profit... et la confirmation pour le -j1 rassure.

Je me lancerai dans la contruction du système uClibc dimanche je pense. Je ferai un petit update pour ceux qui suivent l'affaire.

----------

## Untux

Salut à tous,

Petite confusion de ma part... uClibc remplace glibc et non pas gcc. Bref! Je me suis donc installé, sur une nouvelle partition, un système uClibc à partir d'un stage3 uClibc disponible dans les miroirs gentoo sous experimental/x86/embedded/stages. Premier constat, les compilations sont un peu plus lentes (ex vim : glibc -> 3:30; uClibc -> 6:30). Deuxième constat, les exécutables (USE_FLAGS et versions identiques) sont un peu plus légers (ex vim : glibc -> 2.4M; uClibc -> 1.9M). J'ai essayé de compiler gcc (mise à jour 4.1.1 -> 4.1.1-r1) puisque c'était mon soucis principal. La compilation s'est interrompue après 2 heures, tandis qu'elle s'approchait du fameux « insn-attrtab.o » (dont le traitement avait pris environ 33 heures sur le système glibc). Message d'erreur définitivement incompréhensible pour moi :

```

stage1/xgcc -Bstage1/ -B/usr/i386-gentoo-linux-uclibc/bin/   -pipe -O2 -fprofile-generate -DIN_GCC   -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -pedantic -Wno-long-long -Wno-variadic-macros -Wold-style-definition -Wmissing-format-attribute     -DHAVE_CONFIG_H -DGENERATOR_FILE  -o build/genattrtab \

         build/genattrtab.o build/genautomata.o \

         build/rtl.o build/read-rtl.o build/ggc-none.o build/min-insn-modes.o build/gensupport.o build/insn-conditions.o build/print-rtl.o build/errors.o \

         build/varray.o ../build-i386-gentoo-linux-uclibc/libiberty/libiberty.a -lm

build/genattrtab /var/tmp/portage/gcc-4.1.1-r1/work/gcc-4.1.1/gcc/config/i386/i386.md > tmp-attrtab.c

/bin/sh: line 1:  7037 Killed                  build/genattrtab /var/tmp/portage/gcc-4.1.1-r1/work/gcc-4.1.1/gcc/config/i386/i386.md >tmp-attrtab.c

make[2]: *** [s-attrtab] Error 137

make[2]: Leaving directory `/var/tmp/portage/gcc-4.1.1-r1/work/build/gcc'

make[1]: *** [stageprofile_build] Error 2

make[1]: Leaving directory `/var/tmp/portage/gcc-4.1.1-r1/work/build/gcc'

make: *** [profiledbootstrap] Error 2

!!! ERROR: sys-devel/gcc-4.1.1-r1 failed.

Call stack:

  ebuild.sh, line 1546:   Called dyn_compile

  ebuild.sh, line 937:   Called src_compile

  ebuild.sh, line 1255:   Called toolchain_src_compile

  toolchain.eclass, line 24:   Called gcc_src_compile

  toolchain.eclass, line 1536:   Called gcc_do_make

  toolchain.eclass, line 1410:   Called die

!!! emake failed with profiledbootstrap

!!! If you need support, post the topmost build error, and the call stack if relevant.

```

Mon installation est loin d'être une référence puisque je n'ai strictement aucune idée de l'impact des bidouillages que j'ai fait : par exemple, j'ai fait pointer mon make.profile sur le profil de la xbox, mais dans mon make.conf j'ai repris certains paramètres du profil uclibc :

```

...

CFLAGS="-Os -pipe" 

CHOST="i386-gentoo-linux-uclibc" 

CXXFLAGS="-Os -pipe" 

LDFLAGS="-Wl,-z,relro" 

...

```

Et ça à mon avis, c'est très mal! Des CHOST différents dans make.profile et make.conf... c'est vraiment de la bidouille à 2 balles :p En gros, mes connaissances actuelles sont insuffisantes pour maîtriser cette installation uClibc. Je vais la garder en réserve et reprendre mes expérimentations sur la partition installée avec glibc. J'essaierai sans doute la méthode NFS-chroot proposée par XavierMiller qui me semble, à priori, un peu plus à ma portée.

Mais avant tout, je vais laisser couler un peu d'eau sous les ponts car je suis las :)

----------

## Magic Banana

Je ne crois pas que ce soit mal. Sauf erreur de ma part, les définitions dans /etc/make.conf remplacent celles du profil.

----------

## Untux

Comme prévu, de l'eau a coulé sous les ponts et j'ai essayé la méthode proposée par XavierMiller (nfs/chroot). J'ai d'abord installé NFS en suivant ce  HOWTO - Share directories via NFS, et je me suis ensuite servi de celui-là : HOWTO - Emerge on very slow systems. En résumé ça donne ça :

Sur la xbox

```

# echo "192.168.2.80 h_PIV" >> /etc/hosts

# echo "/ h_PIV(rw,no_root_squash,sync,no_subtree_check)" >> /etc/exports

```

Sur le PIV

```

# echo "192.168.2.100 h_xbox" >> /etc/hosts

# mkdir /{mnt,tmp}/xbox

# /etc/init.d/nsfmount start

# mount h_xbox:/ /mnt/xbox -o rsize=1024,wsize=1024

# mount -o bind /tmp/xbox /mnt/xbox/var/tmp/portage

# mount -t proc none /mnt/xbox/proc

# mount -o bind /dev /mnt/xbox/dev

# mv /etc/make.conf{,.PIV}

# ln -s /{mnt/xbox/,}etc/make.conf

# chroot /mnt/xbox

# emerge <Plein_de_trucs_que_j_aurais_jamais_eu_la_patience_d_installer_sans_l_astuce_proposée_par_XavierMiller>

# exit

# unlink /etc/make.conf

# mv /etc/make.conf{.PIV,}

# umount /mnt/xbox/{dev,proc,var/tmp/portage}

# umount /mnt/xbox

```

J'ai re-emergé gcc, juste pour voir : 1h05, à peine plus que si je l'avais fait pour mon PIV... la différence est donc d'environ 36 heures :] Ensuite j'ai emergé xorg-x11 et ion3 : aucun problème sur plus de 120 paquets. Cette solution frise la perfection. Merci encore à tous ceux qui m'ont gratifié de leur aide.

J'ai laissé tomber le uClibc. D'une part les gains ne semblaient pas très importants et d'autre part j'avais des problèmes que je ne comprenais pas : rallentissements, erreurs de compilation, etc. Mes connaissances sont trop limitées pour essayer de les comprendre et de les résoudre. Sans compter qu'en sortant des standards, on trouve nettement moins de ressources sur... le net.

Si un jour je comprend pourquoi distcc ne fonctionnait pas, je ferai un petit update, mais pour le moment je suis heureux comme ça.

@Magic-Banana: Suite à ton message j'ai regardé d'un peu plus près la structure des profils et tu as tout à fait raison. En l'occurence c'est make.conf qui a le dernier mot. Merci de m'avoir poussé à comprendre un rouage de plus de Gentoo :)

----------

