Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Problème avec "make -j"

20 réponses
Avatar
Eric Levenez
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

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.

10 réponses

1 2
Avatar
Vincent Lefevre
Dans l'article <C3F4CE18.C6E6B%,
Eric Levenez é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).

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 - 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)

Avatar
Eric Levenez
Le 06/03/08 03:26, dans <20080306021858$, « Vincent
Lefevre » <vincent+ a écrit :

Dans l'article <C3F4CE18.C6E6B%,
Eric Levenez é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.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Paul Gaborit
À (at) Thu, 06 Mar 2008 07:39:01 +0100,
Eric Levenez écrivait (wrote):
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/>

Avatar
Eric Levenez
Le 06/03/08 13:58, dans , « Paul
Gaborit » a écrit :


À (at) Thu, 06 Mar 2008 07:39:01 +0100,
Eric Levenez écrivait (wrote):
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.


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...

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Vincent Lefevre
Dans l'article <C3F55015.C6ECA%,
Eric Levenez écrit:

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).

--
Vincent Lefèvre - 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)


Avatar
Eric Levenez
Le 06/03/08 18:20, dans <20080306171647$, « Vincent
Lefevre » <vincent+ 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 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" :-)

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

Avatar
Vincent Lefevre
Dans l'article <C3F5FD0A.C6FB3%,
Eric Levenez écrit:

Le 06/03/08 18:20, dans <20080306171647$, « Vincent
Lefevre » <vincent+ 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.

--
Vincent Lefèvre - 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)


Avatar
Paul Gaborit
À (at) Thu, 06 Mar 2008 19:56:58 +0100,
Eric Levenez écrivait (wrote):

Et maintenant le "make" est plus de 4 fois plus rapide que le "make all" :-)



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.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>

Avatar
Eric Levenez
Le 07/03/08 12:29, dans , « Paul
Gaborit » a écrit :

À (at) Thu, 06 Mar 2008 19:56:58 +0100,
Eric Levenez écrivait (wrote):

Et maintenant le "make" est plus de 4 fois plus rapide que le "make all" :-)


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.


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...).

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Vincent Lefevre
Dans l'article <C3F6EC14.C70BF%,
Eric Levenez écrit:

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.

--
Vincent Lefèvre - 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)

1 2