Terminal: Digitar dentro do terminal WSL padrão é incrível, por que é melhor do que qualquer outro aplicativo?

Criado em 14 dez. 2018  ·  8Comentários  ·  Fonte: microsoft/terminal

Desculpe, isso não é um problema, mas em vez disso, é mais uma sugestão / solicitação para não interromper o que quer que você tenha feito com o terminal WSL padrão (especificamente o Ubuntu) sendo tão responsivo quando se trata de renderizar caracteres na tela após pressionar um chave.

Digitar no terminal WSL padrão parece que você está digitando no ar. Tem uma suavidade que não está presente em nenhum outro aplicativo do Windows, nem mesmo em notepad.exe . Parece que tem 10ms de atraso de entrada em vez de 75ms + para todos os outros Windows (e 200-250ms + para a maioria dos aplicativos baseados em Electron).

O que faz com que o terminal WSL pareça melhor do que notepad.exe e esse aprimoramento da interface do usuário chegará a todos os aplicativos do Windows no futuro?

Sinta-se à vontade para encerrar se não quiser discutir o assunto. Eu o abri principalmente para trazer uma consciência de como é bom evitar que algum tipo de regressão aconteça no futuro.

Issue-Question Product-Conhost

Comentários muito úteis

Eu realmente não me importo quando alguém chega e decide nos dizer que estamos fazendo um bom trabalho. Ouvimos tantas reclamações todos os dias que um post como este é uma lufada de ar fresco. Obrigado pelo seu obrigado!

Além disso, fico feliz em discutir isso com você até que você esteja totalmente cansado de ler. Por favor, pergunte a qualquer continuação que você deseja. Eu gosto de tagarelar sobre meu trabalho. : P

Se eu tivesse que dar um palpite sobre o que está nos tornando mais rápidos do que qualquer outro aplicativo do Windows para colocar seu texto na tela ... Eu diria que é porque esse é literalmente nosso único trabalho! Provavelmente também porque estamos usando quase as APIs mais antigas e de nível mais baixo que o Windows possui para realizar esse trabalho.

Quase tudo o mais que você listou tem algum tipo de camada ou estrutura envolvida, ou muitas, muitas camadas e estruturas, quando você começa a falar sobre Electron e Javascript. Nós não.

Temos uma janela vazia, super não especial, sem controles adicionais anexados a ela. Recebemos nossas chaves alimentadas a partir de um pouco acima do kernel, visto que as estamos processando a partir de mensagens de janela e não de algum tipo de estrutura de eventos comum a praticamente qualquer outra estrutura de IU mais complicada que a nossa (WPF, WinForms, UWP, Elétron). E despejamos nosso texto direto na superfície da janela usando PolyTextOut da GDI sem frescuras.

Mesmo notepad.exe tem pelo menos vários controles em sua janela e está provavelmente (eu não olhei) usando algum tipo de estrutura de biblioteca no controle de edição para descobrir seu layout de texto (que provavelmente está usando outra biblioteca quadro de apoio à internacionalização ...)

Claro, isso também significa que temos trocas. Não oferecemos suporte a textos totalmente internacionais, como quase todos os outros aplicativos. RTL? Sem zona de movimento agora. Pares substitutos e emoji? Estamos chegando lá, mas ainda não. Scripts indianos? Não.

Por que somos assim? Por um lado, conhost.exe é velho como sujeira. Ele tem que usar a camada inferior de metal puro de tudo porque foi criado antes da maioria das outras estruturas serem criadas. E também mantém o nível mais baixo / inferior possível porque é praticamente a primeira coisa que se precisa trazer ao trazer uma nova edição de sistema operacional ou dispositivo antes de ter todas as coisas legais como frameworks ou o que esses frameworks exigem para operar. Também está escrito em C / C ++, que é o mais básico possível.

Esse aprimoramento da IU chegará a outros aplicativos no Windows? Quase certamente não. Eles têm muitas coisas acontecendo, o que é bom e ruim. Tenho inveja da capacidade deles de apenas chamar um método e texto de layout de maneira descomplicada em qualquer idioma, sem calcular pixels manualmente ou me importar com os estilos que se aplicam à sua fonte. Mas meus cálculos manuais de pixels, matemática de regiões sujas, loucura de regiões de rolagem e muito mais fazem com que possamos ir mais rápido do que eles. Também tenho inveja de que quando alguém diz "ei, você pode adicionar uma barra de status na parte inferior da janela", eles podem clicar e arrastar isso para o lugar com sua estrutura de interface do usuário e vai funcionar onde, para nós, sempre foi um item do backlog e me dá azia pensar em implementá-lo.

Tentaremos evitar que regrida? Sim! No momento, é uma espécie de processo manual. Identificamos que algo está ficando lento e então pegamos o WPR e começamos a rastrear. Nós olhamos para os caminhos quentes e tentamos raciocinar o que está acontecendo e então melhorá-los. Por exemplo, no último ciclo ou dois, nos concentramos nas alocações de heap como uma área principal onde poderíamos melhorar nosso desempenho de ponta a ponta, mudando uma tonelada de nosso código para usar fachadas semelhantes a iteradores construídas em pilha sobre a solicitação subjacente buffer em vez de traduzir e alocá-lo em um novo espaço de heap para cada nível de processamento.

Como um aparte, @bitcrazed quer que automatizemos os testes de desempenho de alguma maneira muito específica, mas ainda não descobri um ambiente controlado para fazer isso. O Sistema de Engenharia do Windows executa testes de desempenho todas as noites que nos fornecem uma forma grosseira de saber se cometemos algum problema em todo o sistema operacional e, tecnicamente, eles oferecem uma maneira refinada de inserirmos nossos próprios testes de desempenho ... mas eu só não tenho isso ainda. Se você tem uma ideia de uma maneira de fazermos isso de maneira automatizada, sou todo ouvidos.

Se houver mais alguma coisa que você gostaria de saber, me avise. Eu poderia continuar durante todo o dia. Excluí 15 tangentes desta resposta antes de postá-la ....

Todos 8 comentários

Eu realmente não me importo quando alguém chega e decide nos dizer que estamos fazendo um bom trabalho. Ouvimos tantas reclamações todos os dias que um post como este é uma lufada de ar fresco. Obrigado pelo seu obrigado!

Além disso, fico feliz em discutir isso com você até que você esteja totalmente cansado de ler. Por favor, pergunte a qualquer continuação que você deseja. Eu gosto de tagarelar sobre meu trabalho. : P

Se eu tivesse que dar um palpite sobre o que está nos tornando mais rápidos do que qualquer outro aplicativo do Windows para colocar seu texto na tela ... Eu diria que é porque esse é literalmente nosso único trabalho! Provavelmente também porque estamos usando quase as APIs mais antigas e de nível mais baixo que o Windows possui para realizar esse trabalho.

Quase tudo o mais que você listou tem algum tipo de camada ou estrutura envolvida, ou muitas, muitas camadas e estruturas, quando você começa a falar sobre Electron e Javascript. Nós não.

Temos uma janela vazia, super não especial, sem controles adicionais anexados a ela. Recebemos nossas chaves alimentadas a partir de um pouco acima do kernel, visto que as estamos processando a partir de mensagens de janela e não de algum tipo de estrutura de eventos comum a praticamente qualquer outra estrutura de IU mais complicada que a nossa (WPF, WinForms, UWP, Elétron). E despejamos nosso texto direto na superfície da janela usando PolyTextOut da GDI sem frescuras.

Mesmo notepad.exe tem pelo menos vários controles em sua janela e está provavelmente (eu não olhei) usando algum tipo de estrutura de biblioteca no controle de edição para descobrir seu layout de texto (que provavelmente está usando outra biblioteca quadro de apoio à internacionalização ...)

Claro, isso também significa que temos trocas. Não oferecemos suporte a textos totalmente internacionais, como quase todos os outros aplicativos. RTL? Sem zona de movimento agora. Pares substitutos e emoji? Estamos chegando lá, mas ainda não. Scripts indianos? Não.

Por que somos assim? Por um lado, conhost.exe é velho como sujeira. Ele tem que usar a camada inferior de metal puro de tudo porque foi criado antes da maioria das outras estruturas serem criadas. E também mantém o nível mais baixo / inferior possível porque é praticamente a primeira coisa que se precisa trazer ao trazer uma nova edição de sistema operacional ou dispositivo antes de ter todas as coisas legais como frameworks ou o que esses frameworks exigem para operar. Também está escrito em C / C ++, que é o mais básico possível.

Esse aprimoramento da IU chegará a outros aplicativos no Windows? Quase certamente não. Eles têm muitas coisas acontecendo, o que é bom e ruim. Tenho inveja da capacidade deles de apenas chamar um método e texto de layout de maneira descomplicada em qualquer idioma, sem calcular pixels manualmente ou me importar com os estilos que se aplicam à sua fonte. Mas meus cálculos manuais de pixels, matemática de regiões sujas, loucura de regiões de rolagem e muito mais fazem com que possamos ir mais rápido do que eles. Também tenho inveja de que quando alguém diz "ei, você pode adicionar uma barra de status na parte inferior da janela", eles podem clicar e arrastar isso para o lugar com sua estrutura de interface do usuário e vai funcionar onde, para nós, sempre foi um item do backlog e me dá azia pensar em implementá-lo.

Tentaremos evitar que regrida? Sim! No momento, é uma espécie de processo manual. Identificamos que algo está ficando lento e então pegamos o WPR e começamos a rastrear. Nós olhamos para os caminhos quentes e tentamos raciocinar o que está acontecendo e então melhorá-los. Por exemplo, no último ciclo ou dois, nos concentramos nas alocações de heap como uma área principal onde poderíamos melhorar nosso desempenho de ponta a ponta, mudando uma tonelada de nosso código para usar fachadas semelhantes a iteradores construídas em pilha sobre a solicitação subjacente buffer em vez de traduzir e alocá-lo em um novo espaço de heap para cada nível de processamento.

Como um aparte, @bitcrazed quer que automatizemos os testes de desempenho de alguma maneira muito específica, mas ainda não descobri um ambiente controlado para fazer isso. O Sistema de Engenharia do Windows executa testes de desempenho todas as noites que nos fornecem uma forma grosseira de saber se cometemos algum problema em todo o sistema operacional e, tecnicamente, eles oferecem uma maneira refinada de inserirmos nossos próprios testes de desempenho ... mas eu só não tenho isso ainda. Se você tem uma ideia de uma maneira de fazermos isso de maneira automatizada, sou todo ouvidos.

Se houver mais alguma coisa que você gostaria de saber, me avise. Eu poderia continuar durante todo o dia. Excluí 15 tangentes desta resposta antes de postá-la ....

Falando em APIs do Windows de baixo nível, descobri que todos os componentes do _modo de usuário_ do Console (conhost.exe, cmd.exe ...) e WSL (wsl.exe, LxssManager.dll ...) usam C ++ _STL_ enormemente. Por exemplo, na manipulação de strings, alocação de memória, tabelas virtuais, etc. Haverá alguma melhoria de desempenho se apenas C for usado?

Eu não consideraria isso como usando C ++ STL "enormemente". Eles definitivamente usam algumas das coleções e talvez um pouco de manipulação de strings e um algoritmo aqui ou ali. Eu sinto que há muito mais no STL do que essas poucas partes.

Mas de qualquer maneira ... a maioria das coisas que você descreve foi escrita em C há algum tempo. Temos usado seletivamente C ++ e STL em mais e mais deles como uma compensação consciente. Desde que estejamos bem cientes do que os modelos estão fazendo nos bastidores e façamos uso cuidadoso dos corretos, geralmente estamos negociando apenas uma quantidade muito pequena de desempenho enquanto obtemos uma quantidade significativa de segurança e facilidade de programação.

A segurança é na verdade o grande motivo pelo qual usamos modelos STL em vez de tentar criar nossas próprias estruturas, sempre que possível. O uso de modelos STL para coleções e strings geralmente nos concede uma verificação de limites que, de outra forma, teria que ser feita manualmente de forma propensa a erros (ou nem mesmo feita!)

Além disso, não estou estritamente certo de que ter 17 implementações diferentes de enfileiramento e lista vinculada dentro do código do console, quando era C direto, era geral melhor para desempenho do que usar std :: queue e std :: list hoje. Provavelmente consumiu mais espaço em disco para cada implementação individual, o que é um tipo diferente de problema de desempenho (armazenamento e E / S de carregamento de página).

Muito obrigado por dedicar seu tempo para escrever essa resposta, e sem problemas com os elogios.

Nos últimos meses, estive procurando por uma boa configuração de terminal e acho que ubuntu.exe com tmux é o mais próximo da perfeição que você pode obter com as ferramentas que temos hoje. O próprio terminal ubuntu.exe é extremamente rápido e o tmux oferece todas as vantagens do Qualify of Life (guias, painéis divididos, pesquisa de buffer, etc.).

Realmente ansioso por lançamentos futuros que tornem os temas de cores mais compatíveis e aprimoramentos relacionados às propriedades, como teclas de atalho para aumentar o zoom +/- no tamanho da fonte.

@miniksa : Obrigado por um post muito interessante!

estamos usando quase as APIs mais antigas e de nível mais baixo que o Windows possui para realizar esse trabalho.

Já faz um tempo que estou curioso sobre isso. Você parece estar se referindo às várias APIs do Win32 (USER32 / GDI32). Ultimamente, fiquei inseguro sobre se eles ainda são de baixo nível como se pode obter nas versões recentes do Windows (8.0 e posterior), ou se essas APIs foram silenciosamente convertidas para ficar em cima de outras coisas (como Direct2D, DirectWrite, etc.). Como as APIs mais antigas se relacionam com as mais recentes? Eu adoraria se você pudesse esclarecer essa parte!

@stakx , estou me referindo a USER32 e GDI32.

Vou lhe dar uma visão geral superficial do que sei de início, sem gastar horas confirmando os detalhes. Como tal, parte disso está sujeito a acenar à mão e pode estar ligeiramente incorreto, mas provavelmente está na direção certa. Considere cada declaração como meu conhecimento pessoal sobre como o mundo funciona e sujeita a opinião ou erro.

Para a parte gráfica do pipeline (GDI32), as partes do modo de usuário do GDI estão muito baixas. O aplicativo chama GDI32, algum trabalho é feito nessa DLL no modo de usuário e, em seguida, uma chamada de kernel salta para o kernel e ocorre o desenho.

A parte que você está pensando em "converter silenciosamente para sentar em cima de outras coisas" é provavelmente que, uma vez que atingimos as chamadas do kernel, um monte de coisas do kernel GDI tendem a ser re-plataforma sobre as mesmas DirectX quando é realmente gerenciado pela NVIDIA / AMD / Intel / etc. driver gráfico e a GPU na parte inferior da pilha. Acho que isso aconteceu com a re-arquitetura do driver gráfico que veio como parte do WDDM para Windows Vista. Existe um documento em algum lugar sobre quais chamadas ainda são realmente rápidas no GDI e quais são mais lentas como resultado da re-plataforma. A última vez que encontrei esse documento e verifiquei, estávamos usando os mais rápidos.

Além do GDI, acredito que há coisas como Common Controls ou comctl32.dll que forneciam conjuntos reutilizáveis ​​de botões e elementos para criar suas interfaces de usuário antes de termos estruturas declarativas mais agradáveis. Na verdade, não os usamos no console (exceto na folha de propriedades do menu do botão direito).

Quanto ao DirectWrite e D2D e D3D e DXGI em si, eles são um conjunto separado de comandos e caminhos que estão completamente fora do GDI em todos no modo de usuário e kernel. Eles não estão realmente relacionados, exceto que há algumas disposições de interoperabilidade entre os dois. A maioria de nossas outras estruturas de IU tendem a ser construídas no topo da pilha DirectX. XAML com certeza. Eu acho que WPF é. Não tenho certeza sobre WinForms. E acredito que a pilha de composição e o gerenciador de janelas também estão usando DirectX.

Quanto à parte de entrada / interação do pipeline (USER32), tendo a descobrir que a maioria das outras coisas mais novas (pelo menos para PCs desktop) são construídas em cima do que já está lá. O conceito principal do USER32 são janelas e identificadores de janela e tudo é enviado para um identificador de janela. Contanto que você esteja em uma máquina desktop (ou um laptop ou qualquer outra coisa ... quero dizer uma máquina Windows de estilo clássico), há um identificador de janela envolvido e mensagens flutuando e isso significa que estamos falando de USER32.

A fila de mensagens da janela é apenas um FIFO direto (mais ou menos) de qualquer entrada que tenha ocorrido relevante para aquela janela enquanto ela está em primeiro plano + tudo o que foi enviado para a janela por outros componentes do sistema.

As novas tecnologias e estruturas como XAML e WPF e WinForms tendem a receber as mensagens da fila de mensagens da janela de uma forma ou de outra e processá-las e transformá-las em retornos de chamada de eventos para vários objetos que provisionaram em seu mundo.

No entanto, as tecnologias mais recentes que também funcionam em outras plataformas que não são de desktop, como o XAML, tendem a ter a capacidade de processar coisas de uma pilha não USER32 completamente diferente também. Há uma pilha paralela separada para o USER32 com todas as nossas inovações e realizações sobre como a entrada e a interação devem ocorrer, o que não lida exatamente com as filas de mensagens clássicas e os gerenciadores de janela da mesma maneira. Esta é toda a família Core * de coisas como CoreWindow e CoreMessaging. Eles também têm um conceito diferente de "o que é um usuário" que não é tão centrado em sua bunda em uma cadeira com rodinhas em frente a uma tela com um teclado e mouse na mesa.

Agora, se você estiver no XAML ou em um dos outros Frameworks ... toda essa complexidade é tratada para você. O XAML descobre como desenhar no DirectX para você e negocia com o compositor e o gerenciador de janelas para efeitos interessantes em seu nome. Ele descobre se deseja obter seus eventos de entrada do USER32 ou Core * ou qualquer outro de forma transparente, dependendo da sua plataforma e as pilhas de entrada podem lidar com caneta, toque, teclado, mouse e assim por diante de uma maneira unificada. Ele contém disposições embutidas para fazer todos os tipos de globalização, acessibilidade, interação de entrada, etc. que tornam sua vida mais fácil. Mas você pode escolher ir diretamente para o nível inferior e lidar com isso sozinho ou pular o tratamento com o que você não se importa.

O truque é que GDI32 e USER32 foram projetados para um mundo limitado com um conjunto limitado de comandos. Os desktops eram a única coisa que existia, um único usuário no teclado e mouse, saída gráfica simples para um monitor VGA. Portanto, usá-los diretamente no "nível baixo" como o conhost faz é muito fácil. As novas plataformas poderiam ser usadas no "nível baixo", mas são ordens de magnitude mais complicadas porque agora respondem por tudo o que aconteceu com a computação pessoal em mais de 20 anos, como fatores de forma diferentes, vários usuários ativos, vários adaptadores gráficos, e assim por diante e assim por diante. Portanto, você tende a usar uma estrutura ao usar as coisas novas para que sua cabeça não exploda. Eles lidam com isso para você, mas lidam com mais do que antes, então são mais lentos até certo ponto.

Então, o GDI32 e o USER32 são "mais baixos" do que as coisas novas? Tipo de.
Você consegue chegar tão baixo com as coisas mais novas? Quase sempre sim, mas você provavelmente não deveria e não quer.
O novo vive em cima do antigo ou o velho é reformulado no novo? Às vezes e / ou parcialmente.
Basicamente ... é como a resposta para qualquer software ... "é um desastre absoluto e se todos recuarmos por um momento, ficaremos surpresos por ele funcionar." : P

De qualquer forma, isso é passeio o suficiente por uma manhã. Esperançosamente, isso respondeu às suas perguntas e deu a você um pouco mais de visão.

Esperançosamente, isso respondeu às suas perguntas e deu a você um pouco mais de visão.

@miniksa , sim! Faz todo o sentido também. Muito obrigado por dedicar seu tempo para escrever tudo isso! : +1:

Vou encerrar esse problema por enquanto. Obrigado pela consulta e fico feliz que tenha gostado da informação.

Esta página foi útil?
0 / 5 - 0 avaliações