AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 483777
Accepted
Lassi
Lassi
Asked: 2018-11-24 13:17:08 +0800 CST2018-11-24 13:17:08 +0800 CST 2018-11-24 13:17:08 +0800 CST

Por que os emuladores de terminal ainda têm tela piscando?

  • 772

Por que ainda existem artefatos visuais quando os emuladores de terminal desenham aplicativos baseados em texto? Isso em computadores recentes que renderizam jogos 3D e janelas GUI, incluindo fontes vetoriais com suavização de serrilhado sem artefatos.

Vejo regularmente os seguintes artefatos que revelam etapas intermediárias do processo de atualização de tela:

  • Movimento do cursor do terminal (o cursor pisca ou salta pela tela durante a atualização)
  • Rasgando (parte da tela mostra coisas antigas enquanto outra parte mostra coisas novas)
  • Rolagem (a rolagem é perceptível, em vez da nova posição de rolagem ser mostrada imediatamente)

Os artefatos são vistos apenas por intervalos de menos de um segundo, e não durante a maioria das atualizações de tela, mas tendo crescido em GUIs sem cintilação, eu ainda gostaria de saber como evitá-los. Todos os artefatos acima (exceto rolagem) podem ser vistos, por exemplo, no vídeo ASCIInema a seguir, uma vez que ele começa a desenhar as telas mais complexas: MapSCII - o mundo inteiro em seu console!

Também não estou falando especificamente sobre atualizações lentas. Seria bom se as atualizações fossem sempre instantâneas, mas isso nem sempre é possível devido a atrasos na rede e no processamento. O que quero dizer aqui é que telas parcialmente desenhadas geralmente são visíveis por um breve momento. Na maioria das GUIs modernas, apenas telas totalmente finalizadas são mostradas ao usuário, e artefatos de desenho parcial são muito raros.

É minha impressão que o pipeline de emulação de terminal é algo assim:

  1. O usuário pressiona uma tecla no teclado
  2. Kernel passa o pressionamento de tecla do driver do teclado para o sistema de janelas
  3. O sistema de janelas passa o pressionamento de tecla para o emulador de terminal
  4. O emulador de terminal passa o pressionamento de tecla para o dispositivo de kernel pseudoterminal (pty)
  5. Pty interpreta o pressionamento de tecla e passa o resultado para o aplicativo baseado em texto
  6. O aplicativo executa o comando em resposta ao pressionamento de tecla
  7. O aplicativo renderiza uma nova tela (grade de células de caracteres) para o buffer interno
  8. Chamadas de aplicativos cursesou outra biblioteca para converter a grade de células de caracteres em códigos de escape ANSI que renderizarão uma tela equivalente no terminal
  9. A biblioteca grava esses códigos de escape ANSI no dispositivo pty
  10. Pty processa os dados escritos de alguma forma
  11. O emulador de terminal lê dados processados ​​de pty em alguns pedaços
  12. O emulador de terminal chama o sistema de janelas para renderizar o resultado dos códigos de escape ANSI na janela do terminal

Qual das etapas acima pode retardar o processo o suficiente para que o emulador de terminal nos mostre etapas intermediárias de renderização em vez de mostrar apenas o resultado final?

  • Parece que a velocidade dos terminais de hardware (conexões de porta serial) é ditada por sua taxa de transmissão, que pode ser alterada tcsetattr(), mas li em várias fontes que a configuração da taxa de transmissão não tem efeito nos dispositivos pseudoterminais (pty) usados ​​​​pelo terminal emuladores. Isso significa que os kernels Unix não limitam deliberadamente as comunicações pty?

  • Os aplicativos ou bibliotecas de renderização (curses, etc.) enviam texto e códigos ANSI em várias gravações em vez de tentar se contentar com apenas uma write()?

  • Os kernels Unix têm limites de tamanho em seus buffers de E/S internos, o que afeta coisas como a quantidade máxima de dados que podem ser enviados por um canal sem bloqueio. Isso afeta a renderização de telas de terminal com muitos detalhes (uma tela cheia de texto, muitas cores etc.)? Imagino que o texto combinado e os códigos de escape ANSI poderiam somar tantos dados que não cabem no buffer do driver pty, o que dividiria uma atualização de tela em várias operações de gravação pelo aplicativo e várias leituras pelo emulador de terminal. Se o emulador de terminal estivesse ansioso para exibir os resultados de cada leitura antes de processar a próxima, isso faria com que a exibição piscasse até que a leitura final em um lote fosse processada.

  • Os emuladores de terminal ou drivers pty têm tempos limite deliberados para processamento em lote, de modo que seu comportamento imite mais de perto os terminais de hardware, pareça mais natural ou aborde alguma outra preocupação que foi considerada mais importante do que a velocidade de exibição?

Recentemente tem havido algum esforço para fazer novos emuladores de terminal que renderizem mais rápido (por exemplo, pré-renderizando fontes em texturas OpenGL na memória de vídeo). Mas esses esforços só parecem acelerar a renderização de uma grade de células de caracteres em um bitmap de tela uma vez que a grade foi calculada.

Parece haver algo mais acontecendo que torna essas coisas fundamentalmente lentas, mesmo em um computador muito rápido. Pense nisso: se o emulador de terminal processa todos os códigos ANSI para obter uma grade de células de caracteres antes de renderizar qualquer coisa em um bitmap de tela, então não importa quão lentas sejam as rotinas de renderização de grade de caracteres para bitmap - deve haver sem cintilação (pelo menos não o tipo de cintilação que claramente parece corresponder ao movimento do cursor em um terminal de hardware, que é o que vemos com frequência). Mesmo que o emulador de terminal levasse um segundo inteiro para desenhar qualquer grade de células de caracteres na tela, simplesmente teríamos um segundo de inatividade, não um segundo de cintilação.

Um problema semelhante é que o Unix cleare os resetcomandos são incrivelmente lentos para o que fazem (da perspectiva de um usuário de GUI, eles não fazem nada mais complexo do que redesenhar um bitmap). Talvez por motivos relacionados.

terminal performance
  • 1 1 respostas
  • 2435 Views

1 respostas

  • Voted
  1. Best Answer
    egmont
    2018-11-24T17:54:01+08:002018-11-24T17:54:01+08:00

    Eu adoraria ouvir mais detalhes sobre como exatamente acionar essas cintilações proeminentes, pois não noto nenhum ao usar meu sistema.

    No meu sistema, o VTE (o mecanismo por trás do GNOME Terminal) pode processar cerca de 10 MB/s de dados recebidos. O desempenho de outros emuladores também não está muito longe disso, talvez dentro de um fator de 3 ou 5 em ambas as direções. Isso muito, deve ser mais do que suficiente para atualizações sem movimentos.

    Tenha em mente que um terminal de tela cheia pode conter algumas dezenas de milhares de células de caracteres. Os caracteres UTF-8 consistem em vários bytes. Alternar para diferentes atributos (cores, negrito etc.) requer sequências de escape que podem ir de 3 a 4 a facilmente 10 a 20 bytes (especialmente com extensões de 256 cores e truecolor). Layouts verdadeiramente complexos podem, portanto, exigir 100 kB ou uma quantidade ainda maior de tráfego. Isso com certeza não pode ser passado pela linha tty em uma única etapa. Estou até incerto se certos aplicativos (ou bibliotecas de desenho de tela) cuidam de armazenar em buffer toda a saída em uma única etapa. Talvez eles apenas usem printf() e deixem o stdio liberá-los a cada 8 kB ou mais. Esta poderia ser outra razão para eles serem um pouco lentos.

    Eu não estou realmente familiarizado com o comportamento de agendamento do kernel, por exemplo, se ele precisa alternar entre os dois processos, bem como os modos de usuário/kernel, ou se eles podem ser executados simultaneamente em uma CPU multi-thread. Eu realmente espero que eles possam rodar simultaneamente em uma CPU multi-core, que a maioria das CPUs são hoje em dia.

    Não há estrangulamento intencional na história. No entanto, pode haver suposições quando os emuladores decidem continuar lendo os dados ou atualizar sua tela. Por exemplo, se o emulador de terminal processar a entrada mais rapidamente do que o aplicativo emite, ele a verá travando após o processamento do primeiro bloco e, portanto, poderá decidir razoavelmente atualizar sua interface do usuário.

    O cursor é provavelmente o mais proeminente a piscar, uma vez que o cursor se move ao longo da tela à medida que o conteúdo está sendo atualizado. Não pode ficar no mesmo lugar. Se o emulador atualizar sua tela apenas uma vez ao receber os dados de entrada e o cursor eventualmente permanecer no mesmo local, essa cintilação provavelmente se tornará visível.

    Você pode estar interessado nesta proposta de atualizações atômicas ( discussões aqui ) que resolveriam principalmente esse problema, se suportadas tanto pelo emulador de terminal quanto pelo aplicativo em execução.

    Você também pode estar interessado em saber por que a experiência de rolagem com o teclado é necessariamente irregular devido a uma interferência entre a taxa de repetição do teclado e a taxa de atualização do monitor, algo que não está piscando em si, mas causa uma experiência desagradável.

    • 4

relate perguntas

  • Procurando por um gerenciador de download de terminal

  • Erro de sintaxe: número fd inválido?

  • traceroute, imprima apenas as informações do gateway

  • Como posso dar uma olhada no ssh?

  • Área de memória Flash Nand de backup

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve