Estou tentando aprender o que significa "pivô para empilhar máquina". Portanto, esta é uma tentativa de esclarecer o entendimento.
A razão para mudar para uma máquina de pilha completa parece ser
As coisas que não são claras para mim são
Também relacionado
Eu também fiquei um tanto surpreso com o fato de a máquina de pilha implicar que ast's não são mais uma forma de modelar o módulo. Tenho trabalhado na compressão de nível um (veja o protótipo de descompressão para detalhes).
Isso me forçou a reconsiderar como implementá-lo. Eu acredito que encontrei um bom substituto para a descompressão Asts (ao considerar) e irei atualizar os documentos de design em um futuro próximo para refletir a nova direção.
@wanderer
Diante do exposto, não é nenhuma surpresa que o pivô para uma máquina de pilha foi decidido por pessoas que trabalham em back-ends de navegador e rejeitado por pessoas envolvidas na transformação ou exibição do Wasm AST.
Isso me forçou a reconsiderar como implementá-lo. Eu acredito que encontrei um bom substituto para a descompressão Asts (ao considerar) e irei atualizar os documentos de design em um futuro próximo para refletir a nova direção.
@KarlSchimpf Eu gostaria muito de ver o que você encontrou para a sua substituição. Temos necessidades de compressão de nível um ligeiramente diferentes. No caso do Ethereums, temos conhecimento global da base de código, então seria bom enviar apenas segmentos do AST que ainda não estão contidos no blockchain ( veja mais aqui ). Gostaria de tentar descobrir se a sua substituição pode ser reutilizada em nosso caso de uso.
Isso não mudará as coisas para o compilador AOT ou JIT de tempo de execução se essa for a preocupação. O decodificador wasm para um compilador otimizado converte o código wasm em SSA, independentemente da codificação. Pode haver algumas pequenas diferenças, como o número inicial de nós phi gerados etc. O código compilado em tempo de execução não lida com a pilha do decodificador (talvez apenas para depuração), embora um compilador muito simples possa emitir um código paralelo à operação da pilha.
Se o operador pick
foi adicionado, então deve ser muito natural traduzir o código de um IR estilo SSA para o código de máquina da pilha wasm. Isso pode ser visto considerando que a fonte para o operador pick
é basicamente uma definição SSA, e se o IR não tivesse expressões (como o llvm), então a tradução é basicamente escolher as definições de fonte e gerar um nova definição de elemento de pilha e uma otimização simples para evitar operações pick
desnecessárias quando uma única definição de uso é consumida na ordem de pilha. Se o IR tiver informações de alcance ao vivo, pick_and_void
também pode ser usado para ajudar ainda mais o tempo de execução do wasm, reduzindo o número de nós phi iniciais.
Talvez você pudesse ver como esse estilo, usando pick
, combinaria com seu RI, consulte https://github.com/WebAssembly/design/issues/753
Estou totalmente a favor da proposta do pick
e pick_and_void
opcodes em vez de set_local
e get_local
. Ele traz muitas possibilidades para otimizações de pilha.
Eu escrevi um pouco sobre a máquina de pilha aqui:
https://docs.google.com/document/d/1CieRxPy3Fp62LQdtWfhymikb_veZI7S9MnuCZw7biII/edit?usp=sharing
Obrigado @titzer por outro artigo útil sobre a máquina de pilha!
É tarde demais para _não_ chamá-lo de tee_local
? As ferramentas Unix não são um modelo de boa nomenclatura. Eu prefiro a sugestão anterior de alguém de set_local
(para não vazio) e store_local
(≡ drop set_local
).
Também não gosto muito de tee_local
, mas, no final das contas, os nomes precisam ser distintos e fáceis de aprender. E é bom pensar que poderíamos adicionar novos operadores que fazem a mesma coisa e chamá-los de tee_*
também. store_local
é confuso porque não toca a memória como os outros store
operadores.
@titzer
void 2, float32
. Isso pareceria muito razoável para um decodificador ou até mesmo um compilador de linha de base.Mesmo sem essa otimização, a quantidade de espaço que os nós vazios consomem parece trivial, mesmo para um compilador de linha de base.
Parece já ter sido decidido que o wasm não é otimizado para interpretação.
Assim, acho que essas razões por si só constituem apenas um caso técnico marginal.
A principal vantagem de um compilador de linha de base parece ser que há menos valores ativos na pilha, e isso é resultado dos operadores set_local e da loja retornando void, que não é um produto do projeto da máquina de pilha.
pick
. Além disso, não é consistente com os benefícios técnicos de ser capaz de anular um elemento na pilha (reduzindo o conjunto ativo para um compilador de linha de base).Um compilador de linha de base não vai alocar registradores para elementos nulos, portanto, essa restrição não faz diferença para o compilador de linha de base.
Os códigos de operação end
e return
precisarão ser desenrolados - o documento afirma o contrário.
Isso garante que os validadores wasm não precisem comparar a pilha de valores de função completa em pontos de fusão de fluxo de controle, em vez disso, apenas o conjunto de valores retidos na pilha. Nesse caso, isso também pode ser uma característica distinta do wasm. Os validadores CIL e JVM precisam comparar todos os valores da pilha?
Acredito que mudar para uma máquina de pilha é míope e um grande erro:
O formato AST pode abrir novas possibilidades para software, algumas das quais são observáveis em linguagens Lispy como Scheme (não as listarei aqui). Em vez disso, estamos tentando prender o mundo do software de volta a este modelo dos anos 60 por mais 50 anos, a partir de uma preocupação equivocada com a otimização do poder.
É como abrir mão do arco porque é mais trabalhoso de criar e, em vez disso, criar uma maneira REALMENTE eficiente de encaixar blocos quadrados. Parabéns, podemos construir pirâmides melhores, mas nunca entenderemos o conceito de catedral.
Para realmente entender meu ponto, IMPORTO a todos vocês que assistam os dois vídeos a seguir na íntegra e pensem bem sobre o que Alan Kay e Douglass Crockford têm a dizer sobre novas ideias, construção de estruturas complexas e deixar algo melhor para a próxima geração:
https://www.youtube.com/watch?v=PSGEjv3Tqo0
Como afirma Alan Kay, o que é mais simples: algo que é mais fácil de processar, mas para o qual o software escrito em cima é enorme; ou um que consome um pouco mais de sobrecarga, mas permite novas maneiras poderosas de modelar software e reduzir a complexidade?
Eu acredito que um modelo AST é um grande começo para inventar "o arco" que está faltando no software, e com algo que irá proliferar em toda a web ... como seria míope abrir mão disso em favor de "otimizar "a coisa velha.
Imagine se em vez de JavaScript, a linguagem da web fosse Java? Lambdas não seria popular; novas maneiras de fazer OOP não seriam pensadas; e todas as bibliotecas incríveis que foram escritas por causa da modelagem de objetos ad-hoc que o JavaScript oferece. Provavelmente uma das linguagens mais confusas e ineficientes já escritas, mas uma das mais poderosas já fornecidas. Vamos lá, vamos dar um passo a mais, tornando-o binário, homoicônico e automedificador.
... e se você for corajoso o suficiente, pense em como a filosofia de "desdobramento da totalidade" de Christopher Alexander se aplica muito mais a um AST do que às máquinas de pilha da década de 1960:
Obrigado.
@ d-cook Mas como uma codificação AST dos mesmos operadores de baixo nível permite 'novas maneiras poderosas de modelar software e reduzir a complexidade'?
Não acho que seja apenas uma questão de AST versus uma pilha de valores, porque ambas as codificações podem ser decodificadas para a forma SSA canonicalizando a diferença para que sejam apenas codificações diferentes do mesmo código.
Wasm não é uma linguagem de alto nível. Pode adicionar objetos no futuro. Javascript não possui inteiros de 64 bits e possui muitas outras restrições. Existem muitas linguagens que podem querer ter como alvo o wasm, e fazer com que elas sejam executadas com mais eficiência na web pode ajudar a explorar mais opções de software. Manter o peso leve do wasm é motivado em parte por questões de segurança, um assunto importante para a web. Se você gosta de Javascript, espera-se que ele tenha suporte na web.
@ d-cook Eu realmente acho que os caras do navegador puxaram o gatilho da máquina de pilha muito cedo. Eles tomaram a decisão em particular e basicamente nos disseram "é assim que vai ser" (a explicação mais antiga que posso encontrar neste repositório está aqui ).
Eles observaram que (1) para o back-end final, a máquina de pilha era ligeiramente mais simples do que o projeto AST original, (2) fornecia oportunidades de otimização ocasionais e (3) a máquina de pilha generaliza bem para processar vários valores (por exemplo, para código que lida com pequenas estruturas). No entanto, como o MVP não suporta (3), não acho que eles deveriam ter finalizado a decisão tão cedo, sem consultar o grupo da comunidade. Como podemos ter certeza de que não havia uma solução simples baseada em AST para o problema de múltiplos valores, quando a comunidade nunca teve a oportunidade de explorar o espaço da solução?
Claramente, a máquina de pilha é melhor para o back-end, mas para outras situações o AST parece melhor. Isso é importante porque, no final das contas, haverá muito mais produtores de Wasm do que consumidores, e os ASTs são melhores para os produtores trabalharem. Um dos recursos do Wasm que considero superimportante (embora não tenha certeza se o MVP o suporta) é a geração de código em tempo de execução. Se você está gerando código dentro do navegador, provavelmente é mais conveniente produzir um AST, caso em que você teria que incluir uma camada de conversão de AST para máquina de pilha, o que aumentará o tamanho do download. Algumas pessoas não vão querer aumentar o tamanho, então haverá uma "divisão" nas melhores práticas à medida que duas abordagens diferentes surgem, uma otimizada para o tamanho do download e a outra por conveniência. Poderíamos ter evitado essa divisão se os navegadores estivessem dispostos a envolver a comunidade - mas também é possível que não tivéssemos descoberto uma maneira de obter benefícios comparáveis de um AST e teríamos mudado para uma máquina de pilha de qualquer maneira.
De qualquer forma, eles se decidiram há três meses, e acho que agora temos que conviver com isso. O back-end do Wasm mais popular,
Eu acredito que um modelo AST é um grande começo para inventar "o arco" que está faltando no software, e com algo que irá proliferar em toda a web ... como seria míope abrir mão disso em favor de "otimizar "a coisa velha.
Observe que o wasm foi projetado para ser de nível muito baixo para que possa produzir código de máquina de alto desempenho com rapidez e facilidade. Acho que é parte do motivo pelo qual ele não modela explicitamente as estruturas de dados como o CLR e a JVM fazem. Outra razão é que eles estão se concentrando em linguagens de sistema como C ++ como um alvo de compilação primeiro; Acho que é porque já temos JavaScript e eles querem se concentrar nas coisas para as quais JS é menos adequado ...
Portanto, mesmo que fosse baseado em AST, gerar código wasm diretamente não seria especialmente conveniente. Notavelmente, o wasm não foi planejado para ser uma linguagem de origem para os desenvolvedores escreverem código diretamente. Há alguma justificativa para isso: os produtores de código wasm devem otimizar o código eles próprios para que o navegador da web não tenha que gastar preciosos clientes. ciclos de CPU laterais em otimizações. Se o wasm fosse de nível muito alto, teria sido menos passível de otimização.
Suspeito que o que você gostaria de ver é semelhante ao que pedi há mais de dois anos: uma máquina virtual com
Wasm MVP não fornece nem os FPs nem os IFs necessários, embora a geração de código em tempo de execução limitado seja possível (não tenho certeza - com alguma ajuda de JS você pode gerar novos módulos em tempo de execução, mas não tenho certeza se esses módulos podem interoperar perfeitamente com o programa original ou ser GC). Os "recursos futuros" incluem vários FPs, mas não IFs.
Você mencionou "toda a web". Acredito que, uma vez que uma VM com FPs seja adicionada a um navegador da web, ela inevitavelmente ficará maior do que a própria web: ela se tornará o ambiente operacional padrão para aplicativos de desktop / móveis também, porque os desenvolvedores não querem escrever duas bases de código para dois ambientes diferentes. A maioria dos desenvolvedores deseja permitir que seu código seja executado na web, então por que não usar esse mesmo código em seus aplicativos não web?
Tudo isso realmente ressalta a importância de acertar o Wasm, então é um pouco decepcionante que os IFs não estejam no plano em lugar nenhum. A boa notícia, porém, é que podemos construir IFs em cima do wasm. De certa forma, é realmente melhor definir IFs separadamente do próprio wasm, porque isso permitirá que as pessoas explorem diferentes conceitos de interoperabilidade sem forçar o navegador da web a criar permanentemente uma única maneira de fazer as coisas. Uma desvantagem é que, ao contrário do wasm, nenhuma empresa está financiando trabalhos de interoperabilidade (se houvesse tal empresa, eu enviaria meu currículo _hoje_ - sou o cara por trás do Loyc.net btw). Outra desvantagem é que a "biblioteca padrão" teria que ser baixada em vez de incluída no navegador da web, mas espero que o cache local resolva esse problema a longo prazo - ou pelo menos, se uma única biblioteca se tornar muito popular .
Na quinta-feira, 3 de novembro de 2016 às 10:38, David Piepgrass [email protected]
escreveu:
@ d-cook https://github.com/d-cook Eu acho que os caras do navegador
puxou o gatilho da máquina de pilha muito cedo. Eles tomaram a decisão
em privado e basicamente nos disse "é assim que vai ser" (o mais antigo
a explicação que posso encontrar neste repositório está aqui
https://github.com/WebAssembly/design/issues/736#issuecomment-236746500
)Eles observaram que (1) para o back-end final, a máquina de pilha foi
ligeiramente mais simples do que o design AST original, (2) fornecia
oportunidades de otimização, e (3) a máquina de pilha generaliza bem para
processamento de vários valores (por exemplo, para código que lida com pequenos
estruturas). No entanto, uma vez que o MVP não suporta (3), eu não acho que eles
deveria ter finalizado a decisão tão cedo, sem consultar o
grupo comunitário. Como podemos ter certeza de que não havia um simples baseado em AST
solução para o problema de múltiplos valores, quando a comunidade nunca foi dada
a oportunidade de explorar o espaço da solução?Exploramos várias soluções diferentes para o problema de múltiplos valores. A maioria
geral teria sido permitir tuplas arbitrárias de escalares para o
língua. Minha experiência nessa direção me levou a acreditar (pessoalmente)
que tuplas são ótimas para uma linguagem de alto nível, mas adicionam muito
complexidade desnecessária para uma linguagem de baixo nível. Idiomas que possuem tuplas
deve simplesmente compilá-los ao direcionar o WebAssembly, da mesma forma que
eles fariam quando tivessem como alvo uma máquina real como o x86.
Implementei vários valores no interpretador e no compilador no V8, e
com o design da máquina de pilha, era de fato uma extensão simples. De outros
as ideias que tínhamos para evitar adicionar tuplas eram limitadas a certas formas de ligação.
Isso exigiria certas verificações sintáticas, mas teria sido mais
complexo (e sujeito a erros!) em back-ends.
Claramente, a máquina de pilha é melhor para o back-end, mas para outros
situações a AST parece melhor. Isso é importante porque, em última análise, haverá
ser muito mais produtores de Wasm do que consumidores, e ASTs são melhores para
produtores para trabalhar. Uma das características do Wasm que considero super
importante (embora eu não tenha certeza se o MVP suporta) é o código de tempo de execução
geração. Se você está gerando código dentro do navegador, provavelmente é
mais conveniente para produzir um AST, caso em que você teria que incluir
uma camada de conversão de AST para máquina de pilha, o que aumentará o
tamanho do download. Algumas pessoas não vão querer aumentar o tamanho, então haverá
ser uma "divisão" nas melhores práticas à medida que surgem duas abordagens diferentes, uma
otimizado para tamanho de download e outro para conveniência. Poderíamos ter
evitou essa divisão se os caras do navegador estivessem dispostos a envolver o
comunidade - mas também é possível que não tivéssemos descoberto uma maneira
para obter benefícios comparáveis de um AST, e teríamos mudado para um
empilhar máquina de qualquer maneira.Para ser claro, nada impede que os produtores usem ASTs internamente. No
na verdade, a máquina de pilha já aceita os mesmos ASTs codificados por pós-pedido que
antes, é apenas que ele aceita _mais_ entradas.
De qualquer forma, eles se decidiram há três meses, e acho que agora nós apenas
tem que viver com isso. O back-end Wasm mais popular, binaryen
https://github.com/webassembly/binaryen , ainda está usando um AST, então
talvez a longo prazo isso constitua a base de um AST padronizado
com base em wasm.Eu acredito que um modelo AST é um grande começo na invenção do "arco"
que está faltando no software e com algo que vai proliferar
toda a web ... como seria míope desistir disso em favor de
"otimizar" a coisa antiga.Observe que o wasm foi projetado para ser de nível muito baixo para que possa produzir
código de máquina de alto desempenho com rapidez e facilidade. Eu acho que faz parte de
por que ele não modela explicitamente as estruturas de dados como o CLR e a JVM fazem.
Outra razão é que eles estão se concentrando em linguagens de sistema como C ++ como um
alvo de compilação primeiro; Acho que é porque já temos JavaScript
e eles querem se concentrar nas coisas para as quais JS é menos adequado ...Portanto, mesmo se fosse baseado em AST, gerar código wasm diretamente não seria
especialmente conveniente. Notavelmente, wasm não se destinava a ser uma fonte
linguagem para os desenvolvedores escreverem o código diretamente.
justificativa para isso: os produtores de código wasm devem otimizar o
codificam-se para que o navegador da web não tenha que gastar preciosos
ciclos de CPU do lado do cliente em otimizações. Se wasm fosse de nível muito alto,
teria sido menos passível de otimização.Eu suspeito que o que você gostaria de ver é semelhante ao que eu pedi
http://loyc.net/2014/open-letter.html mais de dois anos atrás: um virtual
máquina com
- _primitivas flexíveis_ (FPs) que permitem quase todas as
linguagens de programação para funcionar com eficiência, incluindo lixo opcional
coleção, geração de código em tempo de execução (se não literalmente "auto-modificadora
código ") e, espero, troca de pilha (fibras leves para
habilitar corrotinas).- _recursos de interoperabilidade_ (IFs) que permitem programação diferente
linguagens para se comunicarem em um nível muito mais alto do que C / C ++, por
modelar tipos de dados e fornecer uma biblioteca padrão de estruturas de dados.Carta incrível! É a primeira vez que vejo isso. Eu acho que muitos de nós
no esforço WebAssembly gostaria de obter exatamente o que você descreve.
No entanto, também temos que encontrar uma maneira incremental lá. Focando em
recursos de baixo nível agora para idiomas nativos é uma vitória fácil, uma vez que
não se sobrepõe ao domínio do JavaScript. No entanto, outros idiomas irão
transpilar para a web, e gostaríamos de explorar como fazer um objeto de baixo nível
sistema como uma extensão do WASM que pode permitir que seja alvo de muitos
línguas.Wasm MVP não fornece nem os FPs nem os IFs necessários, embora limitados
a geração de código em tempo de execução pode ser possível (não tenho certeza - com alguma ajuda
de JS você pode gerar novos módulos em tempo de execução, mas não tenho certeza se esses
os módulos podem interoperar perfeitamente com o programa original ou ser GC).
Os "recursos futuros" incluem vários FPs, mas não IFs.Você mencionou "toda a web". Eu acredito que uma vez que uma VM com FPs é adicionada
para um navegador da web, ele inevitavelmente se tornará maior do que a própria web:
se tornará o ambiente operacional padrão para aplicativos de desktop / móveis também,
porque os desenvolvedores não querem escrever duas bases de código para duas diferentes
ambientes. A maioria dos desenvolvedores deseja permitir que seu código seja executado no
web, então por que não usar o mesmo código em seus aplicativos não-web?Tudo isso realmente ressalta a importância de acertar o Wasm, então é
um pouco decepcionante que os IFs não estejam no plano em lugar nenhum. O bom
a novidade, porém, é que podemos construir IFs em cima do wasm. De certa forma, é
na verdade, é melhor definir IFs separadamente do próprio wasm, porque
permitem que as pessoas explorem diferentes conceitos de interoperabilidade sem forçar a web
navegador para criar permanentemente uma única maneira de fazer as coisas. Uma desvantagem
é que, ao contrário do wasm, nenhuma empresa está financiando trabalhos de interoperabilidade (se
existisse tal empresa, eu mandaria meu currículo _hoje_ - eu sou o cara
por trás do Loyc.net http://loyc.net/ btw). Outra desvantagem é que o
"biblioteca padrão" teria que ser baixada em vez de incluída no
navegador da web, mas espero que o cache local resolva esse problema em
a longo prazo - ou pelo menos, se uma única biblioteca se tornar muito
popular.É difícil especular sobre o que exatamente formam os recursos de interoperabilidade
deve levar. Chegaremos a isso no devido tempo, espero. Meu projeto pessoal
prefácio para se concentrar em alguns importantes, composíveis
primitivos - mecanismos, não políticas. A interoperabilidade de linguagem pode
espero que funcione como uma camada em cima disso.-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/WebAssembly/design/issues/755#issuecomment -258097594,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/ALnq1FfgJtG93WLkiNfjIMAoTlzFkNQlks5q6auvgaJpZM4JgSHR
.
Comentários muito úteis
Acredito que mudar para uma máquina de pilha é míope e um grande erro:
O formato AST pode abrir novas possibilidades para software, algumas das quais são observáveis em linguagens Lispy como Scheme (não as listarei aqui). Em vez disso, estamos tentando prender o mundo do software de volta a este modelo dos anos 60 por mais 50 anos, a partir de uma preocupação equivocada com a otimização do poder.
É como abrir mão do arco porque é mais trabalhoso de criar e, em vez disso, criar uma maneira REALMENTE eficiente de encaixar blocos quadrados. Parabéns, podemos construir pirâmides melhores, mas nunca entenderemos o conceito de catedral.
Para realmente entender meu ponto, IMPORTO a todos vocês que assistam os dois vídeos a seguir na íntegra e pensem bem sobre o que Alan Kay e Douglass Crockford têm a dizer sobre novas ideias, construção de estruturas complexas e deixar algo melhor para a próxima geração:
https://youtu.be/oKg1hTOQXoY
https://www.youtube.com/watch?v=PSGEjv3Tqo0
Como afirma Alan Kay, o que é mais simples: algo que é mais fácil de processar, mas para o qual o software escrito em cima é enorme; ou um que consome um pouco mais de sobrecarga, mas permite novas maneiras poderosas de modelar software e reduzir a complexidade?
Eu acredito que um modelo AST é um grande começo para inventar "o arco" que está faltando no software, e com algo que irá proliferar em toda a web ... como seria míope abrir mão disso em favor de "otimizar "a coisa velha.
Imagine se em vez de JavaScript, a linguagem da web fosse Java? Lambdas não seria popular; novas maneiras de fazer OOP não seriam pensadas; e todas as bibliotecas incríveis que foram escritas por causa da modelagem de objetos ad-hoc que o JavaScript oferece. Provavelmente uma das linguagens mais confusas e ineficientes já escritas, mas uma das mais poderosas já fornecidas. Vamos lá, vamos dar um passo a mais, tornando-o binário, homoicônico e automedificador.
... e se você for corajoso o suficiente, pense em como a filosofia de "desdobramento da totalidade" de Christopher Alexander se aplica muito mais a um AST do que às máquinas de pilha da década de 1960:
https://youtu.be/98LdFA-_zfA
Obrigado.