ar: lib.a: Resource temporarily unavailable
Est-ce que quelqu'un connaît une solution à ce problème (genre poser des
verrous sur une ligne de Makefile) ?
--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.
> Quand je compile un Makefile avec l'option -j de make (pour lancer
> plusieurs tâches en même temps), cela se passe bien, sauf pour les
> archives créées avec ar. En effet "ar" n'est pas réentrant et cela
> ce passe mal en général avec un message du genre :
> ar: lib.a: Resource temporarily unavailable
ar n'a pas besoin d'être réentrant. AMHA, c'est simplement un bug
dans les dépendances du Makefile. Pour info, je fais souvent des
compilations avec "make -j2" sous Mac OS X, et je n'ai jamais eu
de problème avec ar (j'ai eu des erreurs avec d'autres choses, mais
il s'agissait de problème de dépendances, qui ont été corrigés).
Un exemple de problème qui peut se poser: lorsqu'une règle génère
plusieurs fichiers (dont certains ne sont donc pas en target), si
bien qu'une dépendance peut être satisfaite avant que l'exécution
de la règle se soit terminée. Il faut donc faire particulièrement
attention à ça en écrivant ses Makefile...
--
Vincent Lefèvre <vin...@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
> Dans l'article <C3F4CE18.C6E6B%use...@levenez.com>,
> Eric Levenez <use...@levenez.com> écrit:
>
>> Quand je compile un Makefile avec l'option -j de make (pour lancer
>> plusieurs tâches en même temps), cela se passe bien, sauf pour les
>> archives créées avec ar. En effet "ar" n'est pas réentrant et cela
>> ce passe mal en général avec un message du genre :
>
>> ar: lib.a: Resource temporarily unavailable
>
> ar n'a pas besoin d'être réentrant. AMHA, c'est simplement un bug
> dans les dépendances du Makefile. Pour info, je fais souvent des
> compilations avec "make -j2" sous Mac OS X, et je n'ai jamais eu
> de problème avec ar (j'ai eu des erreurs avec d'autres choses, mais
> il s'agissait de problème de dépendances, qui ont été corrigés).
Avec "make -j2" cela se passe généralement bien, pas avec "make -j" qui est
beaucoup plus violent (surtout avec une machine rapide et multi-c¦ur).
> Un exemple de problème qui peut se poser: lorsqu'une règle génère
> plusieurs fichiers (dont certains ne sont donc pas en target), si
> bien qu'une dépendance peut être satisfaite avant que l'exécution
> de la règle se soit terminée. Il faut donc faire particulièrement
> attention à ça en écrivant ses Makefile...
Oui, cela peut venir de mon Makefile, mais je ne crois pas. J'ai une
bibliothèque avec plein de fichiers dedans et make appelle "ar" plusieurs
fois simultanément sur cette même bibliothèque : le premier "ar" passe", les
autres non. Le traitement dans "ar" est très rapide, et donc la fenêtre où
les problèmes peuvent survenir est faible, mais elle est là. Je vais quand
même revérifier mon Makefile.
C'est que le Makefile n'est pas écrit pour être effectué en tâches
parallèles... Pour bien faire, il faut que la règle de dépendance de
création de la bibliothèque intègre l'ensemble des fichiers membres
nécessaires et que la bibliothèque soit construite en une seule
commande.
--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Oui, actuellement chaque objet de la bibliothèque est ajouté un à un. Je
vais modifier le Makefile pour appeler une seule fois "ar" par bibliothèque
(mais ce n'est pas évident à cause d'autres problèmes). L'inconvénient de
créer la bibliothèque à la fin est que cela multiplie les fichiers objets
pour rien (enfin presque pour rien), mais cela me permet de compiler plus
vite...
> Avec "make -j2" cela se passe généralement bien, pas avec "make -j"
> qui est beaucoup plus violent (surtout avec une machine rapide et
> multi-c¦ur).
C'est vrai...
> > Un exemple de problème qui peut se poser: lorsqu'une règle génère
> > plusieurs fichiers (dont certains ne sont donc pas en target), si
> > bien qu'une dépendance peut être satisfaite avant que l'exécution
> > de la règle se soit terminée. Il faut donc faire particulièrement
> > attention à ça en écrivant ses Makefile...
> Oui, cela peut venir de mon Makefile, mais je ne crois pas. J'ai une
> bibliothèque avec plein de fichiers dedans et make appelle "ar"
> plusieurs fois simultanément sur cette même bibliothèque : le
> premier "ar" passe", les autres non.
Je ne comprends pas bien:
_ Si ar fait des écritures sur cette bibliothèque, alors évidemment,
c'est un bug de ton Makefile: les dépendances doivent être mises en
place de manière à ne pas avoir deux écritures simultanées sur un
même fichier. C'est une règle de base!
_ Si ar ne fait que des lectures sur cette bibliothèque et que ça
foire à cause de ça, alors c'est un bug de l'OS (qui doit savoir
gérer plusieurs lectures simultanées sur un même fichier).
> _ Si ar fait des écritures sur cette bibliothèque, alors évidemment,
> c'est un bug de ton Makefile: les dépendances doivent être mises en
> place de manière à ne pas avoir deux écritures simultanées sur un
> même fichier. C'est une règle de base!
Oui, mais non. La commande "ar" pourrait très bien gérer les accès multiples
par des verrous ou il pourrait y avoir une commande ou une option dans le
Makefile pour gérer cela. Mon Makefile original était du genre (TRÈS
simplifié) :
l.a : l.a(a.o) l.a(b.o)
l.a(a.o) : a.c
$(CC) $(CFLAGS) -c a.c
$(AR) $(ARFLAGS) l.a a.o
rm a.o
l.a(b.o) : b.c
$(CC) $(CFLAGS) -c b.c
$(AR) $(ARFLAGS) l.a b.o
rm b.o
Je viens de le réécrire de cette façon :
l.a : a.o b.o
$(AR) $(ARFLAGS) l.a a.o b.o
a.o : a.c
$(CC) $(CFLAGS) -c a.c
b.o : b.c
$(CC) $(CFLAGS) -c b.c
Alors, oui cela marche maintenant sans problème avec l'option -j de make,
mais ce n'est pas joli du tout car les objets sont dupliqués (en .o et dans
le .a). Et pour compiler le même source de différentes façons pour obtenir
différentes versions d'une bibliothèque, cela duplique et complique tout. La
gestion du contenu des bibliothèques par "l.a(a.o)" n'est ainsi plus
utilisable du tout dans les Makefile. "C'est bien dommage"©
Enfin bon si c'est la seule solution... cela me va :-)
Mon Makefile commence par les règles :
all_smp :
$(MAKE) -j`sysctl -n hw.logicalcpu` all
all : $E
Et maintenant le "make" est plus de 4 fois plus rapide que le "make all" :-)
> Le 06/03/08 18:20, dans <20080306171647$23...@prunille.vinc17.org>, « Vincent
> Lefevre » <vincen...@vinc17.org> a écrit :
> > _ Si ar fait des écritures sur cette bibliothèque, alors évidemment,
> > c'est un bug de ton Makefile: les dépendances doivent être mises en
> > place de manière à ne pas avoir deux écritures simultanées sur un
> > même fichier. C'est une règle de base!
> Oui, mais non. La commande "ar" pourrait très bien gérer les accès
> multiples par des verrous
Quasiment aucun utilitaire ne fait ça (cela serait probablement trop
lourd), sauf quand c'est l'usage courant (e.g. outils gérant des BAL
mail). Et puis la philosophie Unix veut que chaque outil fasse le
minimum...
> ou il pourrait y avoir une commande ou une option dans le
> Makefile pour gérer cela.
C'est à l'auteur du Makefile de le faire via des règles. Dans un de
mes Makefile, j'utilise la commande lockfile pour mettre un verrou.
Ce qui est sympa, c'est de constater que même sur une machine
mono-processeur, plusieurs compilations en parallèle vont plus vite
que séquentiellement. En fait un compilateur passe une bonne partie de
son temps à accéder au disque (le reste étant la compilation
elle-même). Or compilation et accès disque peuvent se faire en
parallèle même avec un seul processeur.
> À (at) Thu, 06 Mar 2008 19:56:58 +0100,
J'utilise aussi "-pipe" comme option de gcc ce qui là aussi permet de mieux
paralléliser les tâches.
Mais il faut voir qu'avec "make -j4" cela lance 4 compilations à la fois,
mais avec une machine 4 c¦urs, cela n'est pas forcément le meilleur choix
car comme tu le dis cela dépend aussi des accès disque. Parfois, c'est "-j3"
par exemple qui est mieux. L'option "-j" seule, qui lance tout en parallèle,
"écroule" la machine quand on a une bibliothèque avec beaucoup de fichiers.
Sur ma machine j'utilise "-j`sysctl -n hw.logicalcpu`" qui a l'avantage
d'être adapté à la machine courante (je n'ai pas encore trouvé la commande
équivalente sur GNU/Linux sur une machine avec un CPU en Hyperthreading...).
> Mais il faut voir qu'avec "make -j4" cela lance 4 compilations à la fois,
> mais avec une machine 4 c¦urs, cela n'est pas forcément le meilleur choix
> car comme tu le dis cela dépend aussi des accès disque. Parfois, c'est "-j3"
> par exemple qui est mieux. L'option "-j" seule, qui lance tout en parallèle,
> "écroule" la machine quand on a une bibliothèque avec beaucoup de fichiers.
C'est un problème avec Mac OS X: quand un processus fait beaucoup
d'accès disque, les performances du système s'écroulent! :( Je le
remarque bien lorsque les tâches effectuées chaque nuit se mettent
en route: lancer un Emacs prend plusieurs dizaines de secondes,
alors que c'est habituellement quasiment immédiat (que la machine
soit chargée ou non). Je n'ai pas ce genre de problème avec Linux.
> Dans l'article <C3F6EC14.C70BF%use...@levenez.com>,
> Eric Levenez <use...@levenez.com> écrit:
>
>> L'option "-j" seule, qui lance tout en parallèle,
>> "écroule" la machine quand on a une bibliothèque avec beaucoup de fichiers.
>
> C'est un problème avec Mac OS X: quand un processus fait beaucoup
> d'accès disque, les performances du système s'écroulent! :(
Je ne parlais pas de cela. Le problème est juste que lancer quelques
dizaines de compilations simultanées (plus que de c¦urs disponibles), cela
ralenti. Idem sur GNU/Linux.
Pour une compilation d'un petit projet, le "-j" par rapport à "-j8" me fait
perdre 2 % de temps, ce qui est négligeable. Le "-j" seul sur un gros projet
je l'avais testé sur du GNU/Linux justement et cela était utilisable ou du
moins le -jN était nettement plus performant.
> Je le
> remarque bien lorsque les tâches effectuées chaque nuit se mettent
> en route: lancer un Emacs prend plusieurs dizaines de secondes,
> alors que c'est habituellement quasiment immédiat (que la machine
> soit chargée ou non). Je n'ai pas ce genre de problème avec Linux.
Je n'échangerais pas mon Mac OS X contre deux barils de GNU/Linux ! :-p
> Le 07/03/08 17:25, dans <20080307162016$31...@prunille.vinc17.org>, « Vincent
> Lefevre » <vincen...@vinc17.org> a écrit :
> > Dans l'article <C3F6EC14.C70BF%use...@levenez.com>,
> > Eric Levenez <use...@levenez.com> écrit:
> >
> >> L'option "-j" seule, qui lance tout en parallèle,
> >> "écroule" la machine quand on a une bibliothèque avec beaucoup de fichiers.
> >
> > C'est un problème avec Mac OS X: quand un processus fait beaucoup
> > d'accès disque, les performances du système s'écroulent! :(
> Je ne parlais pas de cela. Le problème est juste que lancer quelques
> dizaines de compilations simultanées (plus que de c¦urs disponibles), cela
> ralenti. Idem sur GNU/Linux.
Avec des resources infinies (excepté le nombre de cores), ça ne
devrait pas ralentir. Donc c'est peut-être lié: quand on lance
beaucoup de processus simultanés, il y a plus d'accès disque que
dans la normale: swap, plus d'échecs concernant le cache disque...
Ça ralentit sous Linux, mais je trouve que c'est pire sous Mac OS X.
> Ça ralentit sous Linux, mais je trouve que c'est pire sous Mac OS X.
Tous les essais que j'ai effectué m'ont montré que Linux gère mal les
priorités entre processus et thread multiples par rapport à Mac OS X.
D'autres ont le sentiment inverse. Bref, tout dépend de ce que l'on fait et
de comment on le fait.
Il y a quelques jours un article montrait que FreeBSD 7.0 gérait mieux le
SMP que GNU/Linux. Aussitôt des Linuxiens ont démentis montrant qu'en
prenant le tout dernier noyau Linux (non sorti), GNU/Linux était plus
rapide. Si on ne dit pas que "Linux c'est mieux", on est accusé de FUD.
Sur FreeBSD et au moins depuis la version 5, sur une machine
mono-processeur et mono-coeur, les compilations vont beaucoup plus
vite en utilisant 'make -j 4' plutôt que 'make' (testé avec les
compilations du noyau et du monde qui ne sont pas de petits logiciels
puisque c'est *tout* FreeBSD).
Si ce n'est pas le cas sur Mac OS X, c'est peut-être que les priorités
sont gérés différement...
> Sur FreeBSD et au moins depuis la version 5, sur une machine
> mono-processeur et mono-coeur, les compilations vont beaucoup plus
> vite en utilisant 'make -j 4' plutôt que 'make' (testé avec les
> compilations du noyau et du monde qui ne sont pas de petits logiciels
> puisque c'est *tout* FreeBSD).
>
> Si ce n'est pas le cas sur Mac OS X, c'est peut-être que les priorités
> sont gérés différement...
"make -j4" est bien plus rapide que "make" sur ma machine avec Mac OS X,
mais "make -j" est plus lent (idem sur un Linux sur une machine 2 c¦urs).
Mais je n'ai pas de Mac monoc¦ur sous la main pour voir ce que cela fait. Il
n'y a aucune raison que le comportement de Mac OS X soit différent de
FreeBSD ou de GNU/Linux.
D'accord. Là, c'est normal. Un 'make -j' lance brutalement *toutes*
les tâches en parallèles (sauf si il y a dépendance). C'est donc
normal qu'on écroule la machine. Les 'make' actuels ne sont pas encore
assez intelligents pour gérer dynamiquement la charge de la machine.
Donc, ça me rassure sur la gestion des priorités de Mac OS X...
> Mais je n'ai pas de Mac monoc¦ur sous la main pour voir ce que cela fait. Il
> n'y a aucune raison que le comportement de Mac OS X soit différent de
> FreeBSD ou de GNU/Linux.
Un 'make -j' (avec beaucoup de trucs parallélisables) écroule
n'importe quel OS (ou tout du moins, écroule les performances
accordées par l'OS à l'utilisateur).
> Eric Levenez <use...@levenez.com> wrote:
>
>> Mais je n'ai pas de Mac monoc¦ur sous la main pour voir ce que cela fait.
>
> Utilise CHUD pour "débrancher" les autres processeurs.
Avant (Mac PPC) j'avais effectivement avec CHUD un onglet dans les
préférences systèmes pour désactiver un processeur (pas un c¦ur). Je n'ai
rien de ça maintenant sur ma machine (Mac Intel). J'ai trouvé "Reggie SE"
qui permet de voir les caractéristiques de 8 CPU, mais le programme ne
semble pas capable de désactiver un processeur ou un c¦ur. Rien trouvé
d'autre sur le sujet.
> Avant (Mac PPC) j'avais effectivement avec CHUD un onglet dans les
> préférences systèmes pour désactiver un processeur (pas un cœur). Je n'ai
> rien de ça maintenant sur ma machine (Mac Intel). J'ai trouvé "Reggie SE"
> qui permet de voir les caractéristiques de 8 CPU, mais le programme ne
> semble pas capable de désactiver un processeur ou un cœur. Rien trouvé
> d'autre sur le sujet.
Chez moi, je l'ai retrouvé dans /Developer/Extras/PreferencePanes.
--
Politically Correct Unix - UTILITIES
The "touch" command has been removed from the standard distribution due
to its inappropriate use by high-level managers.
> Chez moi, je l'ai retrouvé dans /Developer/Extras/PreferencePanes.
Ah, oui, c'est cela. Cela marche bien :-)
J'ai fait quelques essais de compilation d'un petit projet. Pour mieux voir
les effets du -j il aurait fallu un plus gros projet sans bibliothèque (ou
alors fait à la main en une fois).
---
Avec un seul c¦ur :
make -j1 : 18,7 s
make -j2 : 17,7 s
make -j : 17,8 s
Avec une compilation en plus que le nombre de c¦ur, cela va un poil plus
vite, sûrement parce qu'il y a des attentes d'E/S disque. Le "-j" n'écroule
pas le système (pas une grosse compile non plus).
---
Avec 8 c¦urs :
make -j1 : 17,5 s
make -j2 : 8,8 s
make -j4 : 5.3 s
make -j7 : 4,3 s
make -j8 : 4,0 s
make -j9 : 3,9 s
make -j : 4,3 s
Idem qu'avec un seul c¦ur.
> Chez moi, je l'ai retrouvé dans /Developer/Extras/PreferencePanes.
À noter que MenuMeters est incompatible et ne peut marcher avec.