终端模拟器可以和 TTY 1-6 一样快吗?

use*_*537 63 terminal tty

我最近一直在尝试各种终端模拟器,从内置的 gnome-terminal、aterm、xterm、wterm 到 rxvt。我一直在做的测试是按以下顺序进行的:

  1. 打开一个带有 2 个窗格的 tmux 窗口
  2. 左窗格将是一个冗长密集的任务,例如grep a /et/c -r或一个简单的time seq -f 'blah blah %g' 100000
  3. 右窗格将是一个带有语法的 vim 窗口,打开任何超过 100 行代码的文件。

当左窗格打印大量输出时,右窗格似乎非常缓慢且无响应,我尝试在 vim 中滚动,但需要 1-2 秒才能更改。当我尝试按下CtrlC左窗格时,它在停止之前等待超过 10 秒

当我在 TTY 中做同样的事情时(按CTRL+ ALT+( F[1-6])),它不会发生,并且两个窗格都非常敏感。

我已经关闭了一些配置,例如抗锯齿字体、着色、使用默认设置以及更改为 xmonad 和 openbox,但它并没有改变任何东西。

time seq -f 'blah blah %g' 100000这些终端之间的结果并没有真正不同,但是响应能力确实不同,尤其是当我运行 spitted pane tmux(或其他多路复用器)时。仅供参考,我以最大化模式运行所有这些。

我已经阅读了有关帧缓冲终端的内容,但不确定它是如何工作的以及如何使用它来加速我的终端模拟器。

所以我的问题是,是什么让终端模拟器比 TTY 慢得多?有没有可能让它像TTY一样快?也许硬件加速或什么?。我知道的一件事是,我在运行最大化终端模拟器时在 X 服务器中的分辨率是 1920x1080,而当我运行 TTY 时它小于这个,但我不确定这会如何影响性能。

Ale*_*ios 77

当 GUI 终端仿真器打印出一个字符串时,它必须将字符串转换为字体代码点,将代码点发送到字体渲染器,取回位图并通过 X 服务器将该位图blit显示到显示器上。

字体渲染器必须检索字形并运行它们(您是否知道 Truetype/Opentype 字体是在字体渲染器中的虚拟机内运行的程序?)。在运行每个字形的过程中,在字体度量、字距调整(尽管等宽字体和字距调整不能很好地混合)、Unicode 合规性方面做出了大量的决定,这甚至是在我们到达可能使用 sub 的光栅化器之前- 像素寻址。然后终端必须获取字体光栅化器产生的缓冲区并将其传送到正确的位置,处理像素格式转换、alpha 通道(用于子像素寻址)、滚动(涉及更多blitting)等。

相比之下,将字符串写入以文本模式运行的虚拟终端(注意:不是图形控制台)涉及将该字符串写入视频内存。'你好,世界!' 涉及写入 13 个字节(如果您还需要颜色,则为 13 个 16 位字)。X 字体光栅化器甚至还没有开始它的拉伸练习和指关节开裂,我们已经完成了。这就是为什么文本模式在过去几十年中如此重要的原因。这是非常快实施。甚至滚动也比您想象的要容易:即使在古老的基于摩托罗拉 6845 的 MDA 和 CGA 上,您也可以通过将单个 8 位值写入寄存器(可能是 16 位……这太长了)来垂直滚动屏幕。屏幕刷新电路做了剩下的。您实际上是在更改帧缓冲区的起始地址。

同一台计算机上,没有什么可以使图形终端与文本模式终端一样快。但是请记住:有些计算机的文本模式比您在现代计算机上可能看到的最慢的图形终端要慢。最初的 IBM PC 非常糟糕(DOS 做了软件滚动,叹气)。当我在 80286 上看到我的第一个 Minix 控制台时,我对(跳跃)滚动的速度感到惊讶。进步是好的。

更新:如何加速终端

@ poige他的回答中已经提到了三个,但这是我自己的看法:

  • 减小终端的大小。我自己的终端往往会不断增长,直到填满屏幕,而且这样做时速度会变慢。我对图形终端感到恼火和恼火,然后我调整了它们的大小,一切都变得更好了。:)
  • (@poige) 使用不同的终端模拟器。您可以以一些现代功能为代价获得巨大的速度提升。xterm并且rxvt工作得很好,它有一个很棒的终端模拟器。我怀疑您的测试可能表明它们比“现代”的表现更好。
  • (@poige) 不要使用可缩放字体。1986 可能会打电话要求取回它的终端,但你不能否认它们更快。;)
  • (@poige)通过关闭抗锯齿/子像素寻址和提示来简化字体光栅化器。它们中的大多数允许覆盖环境变量,因此您不必全局执行此操作。注意:如果您选择位图字体,则毫无意义。
  • 这会造成最大的伤害:不要使用(多个窗格)tmux ——并排运行两个独立的终端。当tmux显示两个窗格时,它必须使用终端指令来大量移动光标。尽管现代终端库速度非常快并且擅长优化,但它们仍然会从您的原始终端带宽中窃取字节。要将光标移动到兼容 DEC VT 的终端上的任意行,请发送ESC [ row ; col H. 那是 6-10 个字节。使用多个终端,您将工作分开,无需定位、优化、缓冲和所有其他curses工作,并更好地利用多个 CPU 内核。

  • +1,但是 tmux 的事情比发送一些额外的转义码还要复杂。终端旨在滚动整个窗口,而不是其中的一半。因此,当 tmux 必须将左窗格中的所有文本向上移动一行时,它不能只创建一个新行并让终端将其向上移动,它必须重新绘制整个窗格。 (5认同)

poi*_*ige 17

同时@Alexios 已经很好地描述了所有原因,我可以提到几件事,它们相对减轻了痛苦:

  • 使用位图字体(TerminalTerminus——这真的很棒),
  • 关闭抗锯齿,或考虑至少不使用子像素渲染
  • 使用 KDE 的终端 — konsole.

  • `konsole` 进行延迟屏幕更新:它不是立即显示输出,而是等待更多输出,以便“批量”更新。这就是它表现如此出色的原因,以至于完全响应 OP 的压力测试。 (3认同)
  • 很确定字体渲染会在某个时候缓存。我不认为代表字母 f 的像素每次复制到像素图时都会从矢量定义中重新渲染。(除非它必须以新的尺寸或新的角度渲染)。我不会否认有一些非常好的位图字体的事实,如果它们碰巧以您想要的大小存在,那么仅就外观而言这可能是最佳选择。 (3认同)