nproc
fornisce il numero di core/thread della CPU disponibili, ad es. 8 su una CPU quad-core che supporta SMT a due vie.
Il numero di processi che puoi eseguire in parallelo con make
utilizzando il -j
l'opzione dipende da una serie di fattori:
- la quantità di memoria disponibile
- la quantità di memoria utilizzata da ciascun
make
lavoro - la misura in cui
make
i lavori sono legati all'I/O o alla CPU
make -j$(nproc)
è un punto di partenza decente, ma di solito puoi usare valori più alti, a patto che non esaurisci la tua memoria disponibile e inizi a battere.
Per build veramente veloci, se hai abbastanza memoria, ti consiglio di usare un tmpfs
, in questo modo la maggior parte dei lavori sarà legata alla CPU e make -j$(nproc)
funzionerà il più velocemente possibile.
Il modo più diretto è usare nproc
in questo modo:
make -j`nproc`
Il comando nproc
restituirà il numero di core sulla tua macchina. Avvolgendolo nei segni di spunta, il nproc
il comando verrà eseguito per primo, restituirà un numero e quel numero verrà passato a make
.
Potresti avere qualche esperienza aneddotica in cui il conteggio dei core + 1 si traduce in tempi di compilazione più rapidi. Ciò ha più a che fare con fattori come ritardi di I/O, altri ritardi delle risorse e altri limiti di disponibilità delle risorse.
Per farlo con nproc+1
, prova questo:
make -j$((`nproc`+1))
Sfortunatamente anche parti diverse della stessa build possono essere ottimali con valori di fattore j in conflitto, a seconda di cosa viene costruito, come, quali delle risorse di sistema sono il collo di bottiglia in quel momento, cos'altro sta accadendo sulla macchina di costruzione, cosa sta succedendo in la rete (se si utilizzano tecniche di compilazione distribuita), stato/ubicazione/prestazioni dei numerosi sistemi di memorizzazione nella cache coinvolti in una compilazione, ecc.
La compilazione di 100 minuscoli file C può essere più veloce della compilazione di un singolo file enorme o viceversa. La creazione di codice piccolo e altamente contorto può essere più lenta rispetto alla creazione di enormi quantità di codice diretto/lineare.
Anche il contesto della build è importante:l'utilizzo di un fattore j ottimizzato per build su server dedicati ottimizzato per build esclusive e non sovrapposte può produrre risultati molto deludenti se utilizzato dagli sviluppatori che creano in parallelo sullo stesso server condiviso (ognuna di queste build potrebbe richiedere più tempo rispetto a tutti loro combinati se serializzati) o su server con configurazioni hardware differenti o virtualizzati.
C'è anche l'aspetto della correttezza delle specifiche di costruzione. Build molto complesse possono avere race condition che causano errori di build intermittenti con tassi di occorrenza che possono variare notevolmente con l'aumento o la diminuzione del fattore j.
Posso andare avanti e avanti. Il punto è che devi valutare realmente il tuo costruisci nel tuo stesso contesto per il quale si desidera ottimizzare il fattore j. Si applica il commento di @Jeff Schaller:ripeti finché non trovi la soluzione migliore. Personalmente partirei dal valore nproc, proverei prima verso l'alto e verso il basso solo se i tentativi verso l'alto mostrano un degrado immediato.
Potrebbe essere una buona idea misurare prima diverse build identiche in contesti apparentemente identici solo per avere un'idea della variabilità delle tue misurazioni - se troppo alta potrebbe compromettere l'intero sforzo di ottimizzazione (una variabilità del 20% eclisserebbe completamente un miglioramento del 10%/ lettura del degrado nella ricerca del fattore j).
Infine, IMHO è meglio utilizzare un server di lavoro (adattivo) se supportato e disponibile invece di un fattore j fisso:fornisce costantemente prestazioni di compilazione migliori in una gamma più ampia di contesti.