¿Por qué la gente recomienda la opción -j3 para hacer cuando se tiene una CPU de doble núcleo?

18

En Gentoo Linux, es posible configurar la MAKEOPTSvariable /etc/portage/make.confpara indicar makecuántos trabajos debe ejecutar en paralelo al crear paquetes. Como tengo una CPU de doble núcleo, ingenuamente elegí usar la -j2opción: un trabajo por núcleo, por lo que ambos tienen algo que hacer. El "problema" es que hay muchas referencias que le dicen a los usuarios que tienen una CPU de doble núcleo que establezcan la -j3opción. Algunos de ellos son:

Por ejemplo, el manual de Gentoo dice:

Una buena opción es la cantidad de CPU (o núcleos de CPU) en su sistema más uno, pero esta guía no siempre es perfecta.

Pero, ¿cuál es la justificación de la regla "CPU + 1"? ¿Por qué el trabajo extra?

La página del comando man make.conf (5) incluso dice:

La configuración sugerida es entre CPUs + 1 y 2 * CPUs + 1.

También leí la sección 5.4 (Ejecución paralela) en la makepágina de información y la makeexplicación de la página del manual para la -jopción, pero parece que no hay respuestas allí.

Francesco Turco
fuente

Respuestas:

13

No hay una regla simple que siempre funcione. La gente podría recomendar una figura particular porque experimentaron con una compilación particular en una máquina en particular y este fue el mejor escenario, o porque siguieron algún razonamiento que puede o no tener alguna relación con la realidad.

Si está bendecido con mucha RAM, entonces el factor limitante en una compilación larga será el tiempo de CPU. Entonces, una tarea por CPU, más una tarea pendiente para esos bloques de E / S ocasionales, es una buena configuración. Eso lo convierte en -j3una CPU de doble núcleo (o más precisamente, para una máquina de doble CPU, si cada núcleo es hiperprocesado, serían 4 CPU, entonces -j5).

Si tiene muy poca RAM, entonces un factor limitante puede ser que no puede tener muchos trabajos simultáneos, o de lo contrario se seguirán intercambiando entre sí. Por ejemplo, si no puede colocar cómodamente dos instancias del compilador en la memoria, es make -j2posible que ya sea más lento que make. Dado que esto depende de cuántos procesos del compilador puede caber en la RAM a la vez, no hay forma de obtener una cifra general.

En el medio, puede ser beneficioso tener más trabajos. Si cada proceso del compilador es pequeño, pero la compilación en su conjunto toca muchos datos, entonces la E / S del disco puede ser el factor de bloqueo. En este caso, querrá varios trabajos por CPU a la vez, de modo que siempre haya un trabajo con cada CPU mientras otros esperan E / S. Nuevamente, esto depende mucho del trabajo de compilación y de la RAM disponible, aquí de lo que está disponible para el caché de datos (hay un óptimo después del cual tener demasiados trabajos contamina demasiado el caché).

Gilles 'SO- deja de ser malvado'
fuente
No sabía que si los núcleos de CPU son hiperprocesados, cada uno de ellos cuenta como dos. De todos modos, parece que mi CPU no es compatible con Hyper Threading.
Francesco Turco
Acepté esta respuesta. De todos modos, elegí seguir con -j2mi sistema. Esto se debe a que intenté emerger tanto gccy firefoxcon configuraciones de -j1hasta -j5(para un total de 10 comandos emergentes ), y parece que si bien -j2es definitivamente más rápido que -j1, las otras tres configuraciones están a la par -j2.
Francesco Turco
7

Supongo que esto es un poco heurístico : permitir makeiniciar CPUs + 1procesos es asegurarse de que:

  1. no habría una brecha entre un proceso de trabajo que acaba de terminar y un trabajador aún por ejecutar, algo así como la cola de ejecución de llenado previo.
  2. no habría demasiados procesos competitivos para generar gastos generales notables con ese llenado previo de la cola de ejecución.

Pero, de nuevo, eso es heurístico y el manual de FreeBSD todavía lo recomienda make -j4 para una sola CPU.

poige
fuente
5

En general, hay razones para comenzar más trabajos que la cantidad de núcleos. Para la compilación de C usando gcc, si -pipe no está definido en las opciones de gcc, realiza sus acciones (preprocesamiento, primera ejecución, optimizaciones y ensamblaje) en secuencia usando archivos temporales; -pipe cambia esto para usar tuberías entre subprocesos. (Agregar -pipe es predeterminado, por ejemplo, para FreeBSD, pero no es tradicional en Linux). Entonces, si tiene 2 núcleos y permite 2 trabajos en paralelo, pasarán algún tiempo en la E / S de disco. La recomendación de agregar 1 trabajo parece estar relacionada con estos detalles. Pero para obtener la respuesta final, debe encontrar quién y cuándo agregó esta recomendación y preguntarle :) o preguntar en la lista de correo de Gentoo.

Netch
fuente
2

Básicamente ese número es lo que los autores llaman sentido común. En el mejor de los casos, es una buena suposición. Hasta donde yo sé, el proceso de creación que se genera cuando escribe makeya se cuenta para -j3que pueda terminar con el proceso principal en espera, mientras que los otros dos están compilando.

Sin embargo, cuando usaba Gentoo, la regla general era <#cpus>*2 + 1.

Todo depende de lo que su pollo arrastra, las hojas de té o la bola mágica 8 le informan sobre la E / S del disco que debe realizarse y la programación de su núcleo Linux actual. [comenzar el núcleo de esta publicación] Desde mi experiencia personal ( -jno es específica de Gentoo), todo entre #cpus + 1 y #cpus * 2 +1 arroja buenos resultados [finalizar el núcleo de esta publicación] y, en promedio, apenas notará diferencias. Los procesadores y los núcleos son bastante buenos en estos días.

PERO todo esto cambia cuando: a) realmente usa más de una casilla para compilar (du'h) ob) está desarrollando su propio código

-jEs más probable que un atributo superior muestre dependencias previamente desconocidas.

Y en una nota al margen: no vaya por el número de núcleos, sino por el número de flujos simultáneos que toman las CPU. (¡Hypertheading!)

Bananguin
fuente