O que poderia estar causando o travamento ao compilar em vários núcleos?

15

Ontem eu estava tentando compilar o pacote ROOT da fonte. Desde que eu estava compilando em uma máquina monstro de 6 núcleos, eu decidi ir em frente e construir usando múltiplos núcleos usando make -j 6 . A compilação foi suave e muito rápida no início, mas em algum momento make pendurou usando 100% de CPU em apenas um núcleo.

Eu pesquisei e encontrei esta postagem nos quadros de mensagens ROOT . Desde que eu construí este computador, eu estava preocupado que eu não tivesse aplicado corretamente o dissipador de calor ea CPU estava superaquecendo ou algo assim. Infelizmente, eu não tenho uma geladeira aqui no trabalho que eu possa colocar dentro; -)

Instalei o pacote lm-sensors e executei make -j 6 novamente, dessa vez monitorando a temperatura da CPU. Embora tenha ficado alta (perto de 60 C), nunca passou da temperatura alta ou crítica.

Eu tentei executar make -j 4 , mas novamente make parou durante a compilação, desta vez em um ponto diferente.

No final, eu compilei apenas executando make e funcionou bem. Minha pergunta é: por que estava pendurado? Devido ao fato de que ele parou em dois pontos diferentes, eu acho que foi devido a algum tipo de condição de corrida, mas eu acho que make deve ser inteligente o suficiente para colocar tudo na ordem certa, pois oferece o -j opção.

    
por user545424 11.07.2012 / 19:15

5 respostas

11

Eu não tenho uma resposta para este problema específico, mas posso tentar dar uma pista do que pode estar acontecendo: Faltam dependências em Makefiles.

Exemplo:

target: a.bytecode b.bytecode
    link a.bytecode b.bytecode -o target

a.bytecode: a.source
    compile a.source -o a.bytecode

b.bytecode: b.source
    compile b.source a.bytecode -o a.bytecode

Se você chamar make target , tudo será compilado corretamente. A compilação de a.source é executada (arbitrariamente, mas deterministicamente) primeiro. Em seguida, a compilação de b.source é executada.

Mas se os comandos make -j2 target both compile forem executados em paralelo. E você realmente notará que as dependências do seu Makefile estão quebradas. A segunda compilação assume que a.bytecode já está compilado, mas não aparece nas dependências. Portanto, é provável que um erro aconteça. A linha de dependência correta para b.bytecode deve ser:

b.bytecode: b.source a.bytecode

Para voltar ao seu problema, se você não tiver sorte, é possível que um comando permaneça em um loop de 100% da CPU, devido a uma dependência ausente. Isso é provavelmente o que está acontecendo aqui, a dependência ausente não pôde ser revelada por uma construção sequencial, mas foi revelada pela sua construção paralela.

    
por 14.07.2012 / 16:50
2

Não sei há quanto tempo você tem a máquina, mas minha primeira recomendação seria tentar um teste de memória e verificar se a memória está funcionando corretamente. Eu sei que muitas vezes não é a memória que é o problema, mas se for, é melhor eliminá-lo como uma causa antes de tentar rastrear outros problemas provavelmente.

    
por 14.07.2012 / 09:02
1

Sei que essa é uma pergunta muito antiga, mas ainda aparece no topo dos resultados de pesquisa, então aqui está minha solução:

O GNU make tem um mecanismo jobserver para garantir que o make e seus filhos recursivos não consumam mais do que o número especificado de núcleos: link

Ele depende de um pipe compartilhado por todos os processos. Cada processo que deseja obter filhos adicionais precisa primeiro consumir fichas do cano e depois abandoná-las quando terminar. Se um processo filho não retornar os tokens que ele consumiu, o nível superior o fará enquanto estiver aguardando até que eles sejam retornados.

link

Eu encontrei este erro ao construir binutils com o GNU make na minha caixa Solaris, onde "sed" não é o GNU sed. Brincando com o PATH para fazer com que o sed tenha prioridade sobre o sistema, o problema foi resolvido. Eu não sei porque o sed estava consumindo fichas do cachimbo, no entanto.

    
por 29.01.2018 / 21:32
0

seu sistema pode estar ok, mas pode ser uma condição de corrida acontecendo com make quando executado em paralelo.

Se algo estiver errado com o seu sistema, ele irá travar / travar por outros cenários, não apenas ao fazer compilações paralelas.

    
por 14.07.2012 / 14:17
0

Esta pode ser uma condição de corrida, mas também se toda a compilação necessária for feita em paralelo e à espera de outras, a vinculação leva o seu tempo na sua máquina. Eu acho que se o link espera pela compilação anterior necessária em paralelo, então você obtém alta frequência de cpu no encadeamento de links que você compila.

    
por 16.07.2012 / 21:22