Por que as pessoas recomendam a opção -j3 para make quando possuem uma CPU de núcleo duplo?

18

No Gentoo Linux, é possível definir a MAKEOPTSvariável /etc/portage/make.confpara dizer makequantos trabalhos ela deve executar em paralelo ao criar pacotes. Como tenho uma CPU de núcleo duplo, ingenuamente optei por usar a -j2opção: um trabalho por núcleo, para que ambos tenham algo a fazer. O "problema" é que existem muitas referências que dizem aos usuários que possuem uma CPU de núcleo duplo para definir a -j3opção. Alguns deles são:

Por exemplo, o manual do Gentoo diz:

Uma boa opção é o número de CPUs (ou núcleos de CPU) em seu sistema mais uma, mas essa diretriz nem sempre é perfeita.

Mas qual é a justificativa para a regra "CPUs + 1"? Por que o trabalho extra?

A página do manual make.conf (5) diz:

As configurações sugeridas estão entre CPUs + 1 e 2 * CPUs + 1.

Também li a seção 5.4 (Execução Paralela) na makepágina de informações e na makeexplicação da página de manual da -jopção, mas parece que não há respostas lá.

Francesco Turco
fonte

Respostas:

13

Não existe uma regra simples que sempre funcione. As pessoas podem recomendar uma determinada figura porque experimentaram uma compilação específica em uma máquina específica e essa foi a melhor configuração, ou porque seguiram algum raciocínio que pode ou não ter alguma relação com a realidade.

Se você é abençoado com muita RAM, o fator limitante em uma longa compilação será o tempo da CPU. Então, uma tarefa por CPU, mais uma tarefa pendente para os blocos ocasionais de E / S, é uma boa configuração. Isso o torna -j3para uma CPU com dois núcleos (ou, mais precisamente, para uma máquina com dois processadores - se cada núcleo tiver um hyperthread, seriam 4 CPUs -j5).

Se você tem muito pouca memória RAM, um fator limitante pode ser o fato de que você não pode ter muitos trabalhos simultâneos, ou eles continuarão se trocando. Por exemplo, se você não pode caber confortavelmente duas instâncias do compilador na memória, make -j2já pode ser mais lento que make. Como isso depende de quantos processos do compilador você pode caber na RAM de uma vez, não há como derivar uma figura geral.

No meio, pode ser benéfico ter mais empregos. Se cada processo do compilador for pequeno, mas a compilação como um todo tocar muitos dados, a E / S do disco pode ser o fator de bloqueio. Nesse caso, você desejará vários trabalhos por CPU de uma só vez, para que sempre haja um trabalho usando cada CPU enquanto outros aguardam a E / S. Novamente, isso depende muito do trabalho de construção e da RAM disponível, aqui, sobre o que está disponível para o cache de dados (há um ótimo modo após o qual ter muitos trabalhos polui demais o cache).

Gilles 'SO- parar de ser mau'
fonte
Eu não sabia que, se os núcleos da CPU são superencadeados, cada um deles conta como dois. De qualquer forma, parece que minha CPU não suporta Hyper Threading.
Francesco Turco
Eu aceitei esta resposta. De qualquer forma, eu escolhi manter -j2meu sistema. Isso porque tentei emergir tanto gcce firefoxcom configurações de -j1até -j5(para um total de 10 comandos emerge), e parece que, embora -j2definitivamente seja mais rápido -j1, as outras três configurações estão em pé de igualdade -j2.
Francesco Turco
7

Eu acho que isso é meio heurístico - permitir o makelançamento de CPUs + 1processos é garantir que:

  1. não haveria uma lacuna entre um processo de trabalho que acabou de terminar e um trabalhador ainda a ser executado - algo como a fila de execução de preenchimento prévio.
  2. não haveria muitos processos concorrentes para gerar uma sobrecarga perceptível com esse pré-preenchimento da fila de execução.

Mas, novamente, isso é heurístico e o manual do FreeBSD ainda recomenda make -j4 para uma única CPU.

poige
fonte
5

Geralmente, existem razões para iniciar mais trabalhos do que o número de núcleos. Para compilar C usando gcc, se -pipe não estiver definido nas opções gcc, ele executará suas ações (pré-processamento, primeira execução, otimizações e montagem) em sequência usando arquivos temporários; -pipe altera isso para usar pipes entre subprocessos. (Adicionar -pipe é o padrão, por exemplo, para o FreeBSD, mas não é tradicional no Linux.) Portanto, se você tiver 2 núcleos e permitir 2 trabalhos em paralelo, eles passarão algum tempo na E / S do disco. A recomendação para adicionar 1 trabalho parece estar relacionada a essas especificidades. Mas, para obter a resposta final, você deve encontrar quem e quando adicionou esta recomendação e perguntar a ele :) ou perguntar na lista de e-mails do Gentoo devels.

Netch
fonte
2

Basicamente, esse número é o que os autores chamam de bom senso. Na melhor das hipóteses, é um bom palpite. Tanto quanto eu sei, o processo de criação que é gerado quando você digita makejá é contado, portanto, -j3você pode terminar com o processo principal em espera, enquanto os outros dois estão compilando.

No entanto, quando eu usei o Gentoo, a regra geral era <#cpus>*2 + 1.

Tudo depende do que suas trilhas de frango, folhas de chá ou bola mágica 8 informam sobre a E / S do disco que precisa ocorrer e a programação do seu kernel Linux atual. [comece o núcleo deste post] Da minha experiência pessoal ( -jnão é específico do Gentoo), tudo entre #cpus + 1 e #cpus * 2 +1 produz bons resultados [finaliza o núcleo deste post] e, em média, você dificilmente notará diferenças. Processadores e kernels são muito bons atualmente.

MAS tudo isso muda quando: a) você realmente usa mais de uma caixa para compilar (du'h) ou b) está desenvolvendo seu próprio código

-jÉ mais provável que um atributo mais alto mostre dependências anteriormente desconhecidas.

E, em uma nota lateral: não atenda ao número de núcleos, mas ao número de fluxos simultâneos que as CPUs recebem. (Hypertheading!)

Bananguin
fonte