nproc
da la cantidad de núcleos/subprocesos de CPU disponibles, por ejemplo, 8 en una CPU de cuatro núcleos compatible con SMT bidireccional.
El número de trabajos que puede ejecutar en paralelo con make
usando el -j
opción depende de una serie de factores:
- la cantidad de memoria disponible
- la cantidad de memoria utilizada por cada
make
trabajo - la medida en que
make
los trabajos están vinculados a E/S o CPU
make -j$(nproc)
es un lugar decente para comenzar, pero generalmente puede usar valores más altos, siempre que no agote su memoria disponible y comience a trabajar.
Para compilaciones realmente rápidas, si tiene suficiente memoria, recomiendo usar un tmpfs
, de esa manera la mayoría de los trabajos estarán vinculados a la CPU y make -j$(nproc)
funcionará lo más rápido posible.
La forma más directa es usar nproc
así:
make -j`nproc`
El comando nproc
devolverá el número de núcleos en su máquina. Al envolverlo en las marcas, el nproc
el comando se ejecutará primero, devolverá un número y ese número se pasará a make
.
Es posible que tenga alguna experiencia anecdótica en la que hacer un conteo de núcleos + 1 resulte en tiempos de compilación más rápidos. Esto tiene más que ver con factores como retrasos de E/S, otros retrasos de recursos y otras restricciones de disponibilidad de recursos.
Para hacer esto con nproc+1
, prueba esto:
make -j$((`nproc`+1))
Desafortunadamente, incluso diferentes partes de la misma compilación pueden ser óptimas con valores de factor j en conflicto, según lo que se esté compilando, cómo, cuáles de los recursos del sistema son el cuello de botella en ese momento, qué más está sucediendo en la máquina de compilación, qué está pasando en la red (si se utilizan técnicas de compilación distribuida), estado/ubicación/rendimiento de los muchos sistemas de almacenamiento en caché involucrados en una compilación, etc.
Compilar 100 archivos C diminutos puede ser más rápido que compilar uno grande, o viceversa. La creación de código pequeño y muy complicado puede ser más lenta que la creación de grandes cantidades de código directo/lineal.
Incluso el contexto de la compilación es importante:el uso de un factor j optimizado para compilaciones en servidores dedicados y ajustado para compilaciones exclusivas que no se superponen puede generar resultados muy decepcionantes cuando lo usan los desarrolladores que compilan en paralelo en el mismo servidor compartido (cada compilación de este tipo puede tomar más tiempo). tiempo que todos ellos combinados si están serializados) o en servidores con diferentes configuraciones de hardware o virtualizados.
También está el aspecto de la corrección de la especificación de construcción. Las compilaciones muy complejas pueden tener condiciones de carrera que provocan fallas de compilación intermitentes con índices de ocurrencia que pueden variar enormemente con el aumento o la disminución del factor j.
Puedo seguir y seguir. El punto es que tienes que evaluar realmente tu construye en tu mismo contexto para el que desea optimizar el factor j. Se aplica el comentario de @Jeff Schaller:repita hasta que encuentre la mejor opción. Personalmente, comenzaría con el valor nproc, probaría hacia arriba primero y hacia abajo solo si los intentos hacia arriba muestran una degradación inmediata.
Podría ser una buena idea medir primero varias compilaciones idénticas en contextos supuestamente idénticos solo para tener una idea de la variabilidad de sus mediciones; si es demasiado alta, podría poner en peligro todo su esfuerzo de optimización (una variabilidad del 20 % eclipsaría por completo una mejora del 10 %). lectura de degradación en la búsqueda del factor j).
Por último, en mi humilde opinión, es mejor usar un servidor de trabajo (adaptable) si es compatible y está disponible en lugar de un factor j fijo:proporciona un mejor rendimiento de compilación de manera constante en una gama más amplia de contextos.