Estou tentando realmente entender como exatamente uma linguagem de alto nível é convertida em código de máquina e depois executada pela CPU.
Entendo que o código é compilado no código da máquina, que é o código de baixo nível que uma CPU pode usar. Se eu tiver uma declaração de atribuição, diga:
x = x + 5;
y = x - 3;
A CPU executa cada linha uma de cada vez? Portanto, ele primeiro executará x = x + 5; instrução e, em seguida, a próxima instrução que a CPU executará é y = x- 3; Estou realmente tentando entender o processo de execução e como o código que escrevo é realmente executado pela CPU.
computer-science
cpu
Frankie
fonte
fonte
Respostas:
As linhas de código não têm nada a ver com a maneira como a CPU a executa. Eu recomendo a leitura do assembler, porque isso ensinará muito sobre como o hardware realmente faz as coisas. Você também pode obter a saída do assembler de muitos compiladores.
Esse código pode ser compilado em algo como (em uma linguagem assembly criada):
No entanto, se o compilador souber que uma variável não é usada novamente, a operação de armazenamento pode não ser emitida.
Agora, para o depurador saber qual código de máquina corresponde a uma linha de origem do programa, as anotações são adicionadas pelo compilador para mostrar qual linha corresponde a onde no código de máquina.
fonte
ADD Rx, Rx, $5
eSUB Ry, Rx, $3
(assumindo que as variáveis xey foram mapeadas nos registradores). Você está descrevendo uma abordagem RISC de carregamento / armazenamento.Depende.
Nos primeiros dias de máquinas realmente simples, sim, o código executava uma linha de cada vez. À medida que as máquinas se tornaram maiores, mais rápidas e mais complexas, você começou a ver a capacidade de executar várias instruções simultaneamente e a leitura e gravação da memória, demorando muito mais tempo do que as operações nos registradores.
A otimização dos compiladores teve que levar isso em conta, e as linhas fornecidas podem ser executadas "mais ou menos" em paralelo, com uma parte do processador trabalhando no cálculo de y, enquanto outra parte estava armazenando o novo valor anteriormente calculado de x (e o cálculo de y estava usando esse novo valor do registrador).
O Control Data 6600 foi a primeira máquina que conheço que fez esse tipo de coisa. A adição de números inteiros levou 300 nsec, a referência de memória (leitura ou gravação) levou 1000 nsec, multiplica e divide leva muito mais tempo. Até dez instruções podem ser executadas em paralelo, dependendo das unidades funcionais necessárias. Os compiladores CDC 6600 FORTRAN foram MUITO bons em agendar tudo isso.
fonte
x
? Dessa forma, ele já executou o código e o armazenou em cache.Não, não há mapeamento individual entre linhas / instruções de código em idiomas de níveis superior e inferior. De fato, as duas linhas acima são traduzidas em várias instruções de código de máquina , como
Os detalhes reais dessas instruções variam entre as plataformas.
Esta é a visão básica das coisas. No entanto, para complicar ainda mais os problemas, as CPUs modernas aplicam técnicas como pipelines de execução , execução fora de ordem e múltiplos núcleos , entre outros. Isso resulta na CPU fazendo várias coisas ao mesmo tempo, por exemplo, pipelines processam diferentes fases das instruções subseqüentes em paralelo dentro da mesma unidade de processamento, enquanto vários núcleos podem processar instruções independentes em paralelo.
fonte
Você deve procurar grandes detalhes em um livro para encontrar mais detalhes sobre como ele funciona, possivelmente também uma classe de compilador.
Basicamente, sua pergunta está focada em dois aspectos diferentes.
1) Como o código é traduzido em código de máquina?
2) Quando / como o código é calculado usando paralelização?
A resposta para 1) depende do idioma que você usa (embora, por exemplo, seja trivial, a saída seria a mesma). A maneira como o compilador faz a tradução para o código de máquina é uma das forças do idioma. Além disso, existem várias preocupações que precisam ser levadas em consideração no seu exemplo: o código deve carregar os dados na memória, armazená-los etc.
Finalmente, a paralelização é um recurso que você pode forçar do ponto de vista da programação, mas, em poucas palavras, alguns processadores podem tentar pensar que uma parte do código pode ser executada ao mesmo tempo, porque são independentes. No seu caso, claramente, não é o caso, pois você precisa executar as instruções sequencialmente; portanto, não, ele não será executado ao mesmo tempo.
fonte