51 comments

[ 3.2 ms ] story [ 107 ms ] thread
How can going from native 80x25 character mode to graphical mode cause any noticeable slowdown?

It's just text, small textures for the fixed width characters I assume.

Computer games were rendering millions of triangles a second over 20 years ago, even in software rendering engines.

If it's noticeably slow, there must be some unnecessary inefficiencies in there.

I use graphical VTE's like konsole though, which have way more than the in the article mentioned 128x40 characters, on a 4K screen, and I don't notice any slowdown in there at least, it can scroll as fast as you want, with full RGB color codes and unicode characters and 100K lines of scroll history.

Main reason is because it's using it as a linear frame buffer rather than doing anything with textures. The old 80x25 style text modes (on x86 anyway) we're basically 16bit per character on screen with the GPU rendering the text from the byte buffer which made it all highly accelerated.

If you compare to things like Kitty or other GPU accelerated terminals then you'll see the speed you're expecting, but that's not built into the kernel. There is work towards enabling that though via KMSCON but that's not ready for primetime yet.

But 80x25 characters being accelerated mattered maybe in 1992, but not in 2022. This is why I mentioned software rendering as well in my response. People were able to play Unreal without GPU at resolutions like 1280x1024 at full framerates, in 1998.

Does this linear frame buffer have some very restricted bandwidth or something? On modern PC's? Don't all graphics card support VESA modes that are more than fast enough for graphics?

EDIT: as rightfully pointed out, in 1998 Unreal was not feasible at that resolution (it was playable in software mode though, and a 450 MHz pentium II existed). But in 2002 it definitely was for that game, which is also 20 years ago.

In 1998, a 'standard' PC was around a 200MHz Pentium (single core) with a PCI graphics card. Having owned such a machine I can only say it will NOT render Unreal on 1280x1024 at 'full frame rate'. You needed something like a Voodoo card (which didn't do half of the job a full 'GPU' does today) and even then performance tanked at higher resolutions than 640x480 VGA...
It's a sea of anecdotes here, but I confirm that "any middle class" '98 PC could play Half-Life with software rendering adequately at 640x480. But look at any video game, not just 3D - OP's question from performance standpoint is valid.
When did the voodo2 come out? Having two of them in SLI mode, one rendering odd fields and one rendering even fields perhaps?

I did have a voodoo and similar at the time, with the VGA loop lead from the normal 2D card.

I didn’t howver have a working linux install in 1998, as my 2D card was an SIS62something or similar, which wasn’t really supported din redhat 5.2 or perhaps not redhat6. Throw in the issues with using minicom to dial the internet (pay per minute), and having to background it and then invoke pppd, all to use linx, meant I didn’t really do linux until about 2000 when I had the combination of hardware, software (Debian - potato I think) and games (railroad tycoon 2) to make it work.

There's two big limits in graphics rendering: the actual rendering calculations (upgrading to a faster GPU helps here), and transferring data/instructions from CPU RAM to video RAM (using a faster PCI protocol helps here). Getting top-notch graphical performance out of a modern GPU involves carefully designing the system to deliver all the graphics data and instructions for a given frame to the GPU just in time for it to begin rendering, so it has the maximum amount of time to complete the rendering calculations before scanning out the result to the display.

The trouble is, unless we're talking about the operating system for a modern video game console, the kernel is not interested in re-architecting its graphics rendering for maximum throughput, it wants to keep things as simple as possible. That's partially because kernel code needs to be super-reliable, and also because (unlike a modern video game) it needs to support all kinds of output from modern high-end GPUs to simple memory-mapped bitmap displays to character-at-a-time serial ports, so lowest-common-denominator code wins.

In a classic 1990s PC, to write a character to the screen, the CPU can write a single byte directly into the text-display part of the VGA card's memory, and a fraction of a millisecond later the VGA hardware is looking up that byte in the character ROM and sending electrical pulses down the VGA cable.

In a modern PC, if the CPU wants to write a single character to the screen, it probably needs to write each pixel separately, each pixel is three or four bytes, and writing a pixel probably requires making a change to CPU RAM, preparing a command buffer, creating an "update texture" command, uploading the entire screen contents as the new texture, signalling to the GPU that a command buffer is ready, waiting for the GPU to signal that it's ready to receive, sending the command + data, and waiting for the GPU to signal that it's successfully received the data. And then the GPU actually has to draw the output into its own framebuffer, and send that to the monitor.

A modern PC can send all that data much more quickly than a 1990s PC could, but the 1990s PC is much simpler, so it has much less data to send.

1280x1024 at 60 Hz is 78 million pixels per second. Color interpolation and Z buffers multiplies the number of values you work with by 4. Even if there are no overlapping objects, a 333MHz CPU would have to spend just 1 cycle per value to keep full framerate.

The only way you could update the whole screen every frame on these computers was with hardware scrolling, in the style of Mario or Civilization.

Or run at a lower resolution. Quake 2 was 60 Hz on my PC at 320 x 200.
The linux console is still using the framebuffer api instead of DRM. There's not 3d acceleration there yet, so no textures and no shaders. The console is slower than text mode and slower than wayland or x11 with 3d acceleration... which is why konsole feels screaming fast compared to the linux console.
In VGA text mode the VGA hardware is doing the character->texture lookup for you, so you're just sending at most a glyph index worth of data to the card per character.

With modern resolutions what they are, and 16-32 bpp color depths, combined with the unaccelerated dumb linear framebuffer you get with the console framebuffer drivers, it's quite slow relative to a classical VGA text mode.

Even if you still had the same number of lines and columns of text as a classical VGA text mode, just the higher dpi and bpp will still be a lot of bytes for the CPU to move around without any DMA or GPU to assist.

On top of that the VGA console driver in Linux used to exploit the hardware scrolling capabilities which basically just updated an offset register in the VGA instead of having to update the entire screen. IIRC you would lose your console scrollback history by switching virtual consoles because of this implementation. It was blazing fast but the VGA-resident contents were clobbered on VC switch.

I have a distinct memory of very early Linux kernels being able to use higher-resolution native VGA text modes. This would have been around the early 1992 / Linux 0.12 time frame. After being used to my PC showing 80x25 text in MS-DOS, the skinny letters and information-packed display made Linux look like something from the future. :) I suppose it was just a feature of some VGA cards around that time, and Linus decided to support it for a while. The computer historian in me sometimes wonders whatever happened to it.
43 and 50 lines were pretty standard on VGA, so it should be widely supported. I also remember setting 132x50 consoles but that ended up using very few pixels per character (and 80x50 is just that hateful CGA font, vertically compressed) but, at least, it didn’t have serifs.
43 and 50 lines were not high resolution modes, they were just short-character modes. They still use native VGA 720x400 resolution.

There were tools to program VGA card to higher resolution text mode (svgatextmode), and also s3fb supports higher resolution text mode in kernel.

Around 2002 when I was playing with Linux from old Red Hat CDs from a thick book, I did play with SVGATextMode (it is mentioned below)

The system I was experimenting on was a mid-90's 120MHz ancient Packard Bell PC with 56MB of RAM in SIMMs (had that famed bad CMD640 IDE chip). Had a Cirrus Logic VGA adapter onboard.

I remember being able to set all kinds of crazy text resolutions - like lower than 80x25, which was funny.

I also remember in the quest for the highest text resolution - there was some setting about memory clock speed being a controllable setting, higher clock speeds needed for higher text resolutions, and if it was set too fast dots would crawl on the screen.

Early x86/PC Linux versions used VGA's native text capabilities. When ported to m68k machines (Atari/Amiga) that didn't have native text capabilities, that's when Linux grew the virtual console we all know today that renders text to a bitmap display.
(comment deleted)
I can watch the text scroll on my 4k monitor. I suppose it's a lot of pixels to update...
Yes I remember Minix in particular being so fast on my old 386sx. If I would run something that output a lot it would come through so fast there was hardly any scrolling. It was like it just output the last page only. But everything was in the output buffer so this wasn't the case. I've never seen another OS so fast even with a terminal emulator known for speed like kitty.

I didn't have time to read the article yet but I assume those DOS era display cards were just hella optimised for text output.

I remember how mad I was at PCs when the BIOS slowed down text output because CGAs couldn’t keep the video signed up while the computer was writing to video memory.

My Apple II could write text faster than a PC.

> It was like it just output the last page only.

There are times you want the scrolling so you have an idea of how much went by the terminal.

> There are times you want the scrolling so you have an idea of how much went by the terminal.

True, it was not very handy, but I was very impressed :)

Text mode Linux is pretty fast. On Emacs, stuff is almost too fast.

There's a very noticeable difference compared to a X stack known for its low latency (X, no compositor and XTerm).

text mode is pretty fast but slower than Minix's was.

I think part of the reason is that most distros don't use the native text console but use their own (they draw their own characters because 80x25 is not really handy on a 27" display :P ). And I think GPU's don't really optimise this mode like the DOS ones did.

After all, this mode is only ever used for the boot screen (and these days often not even there!). Or perhaps for ESXi or Linux servers, not an important usecase and not something people really interact with on a daily basis anyway.

Well, it's slower. Who cares all that much?

But now it's higher-resolution, while being usable across a very wide variety of hardware, as long as the hardware supports some very simple frame buffer protocol. This is quite useful, because hardware became much more varied.

Not only that, but now it’s possible to support a much richer console than a PC’s text mode ever could. If we wanted, we could do proper bold and italics, smooth scrolling, double width and height, and even sixel/Tektronix/ReGIS graphics.
Adjustable font sizes is already a huge thing for me personally.
I love that too, but I find it sad our si-fi worthy machines can’t do what a VT-220 could in the early 80’s.
I wonder if there isn’t a smarter way to do it if we remember we are not running a terminal, but showing a stream of frames of what a terminal should show at intervals given by the monitor refresh rate. You only need to write to the graphics buffer 60 times a second for most screens. With the kind of processing power we have, we could easily do sub-pixel motion blur for fast moving text.
Precisely! The very first thing the kernel should do (after putting on its socks of course) is to install a terminal shader on the GPU and redirect its output stream to a port on the graphics card.
Think of all the poor souls using KVMs (keyboard video mouse switches) and IPMI consoles to resolve boot issues over the internet, often with latencies in 50 to 100 ms , being on another continent (EU support team working on a server in US).
If you're messing with IPMI consoles, try to get Serial over LAN (SoL) to work. Sometimes it's a bit fussy to get started, but once you do, it's much more pleasant than a remote video console, if you're looking at a text console anyway. The negative is you don't get any scrollback, unless you have an always on console server. If you can get the settings right, most boards with IPMI can also show the BIOS screens on the serial port too; but I've had some servers where I couldn't get that set to matching parameters with the boot loader/OS, so parts of booting would be silent; oh well.
This reminds me of a problem we had with a Windows NT PC app in the late 90s. We ran it with debug output to cmd.com window but didn't understand why there was a slow down. We discovered if we minimized the console window it went so much faster. This was the point I realized debug output can impact race conditions. Definitely an eyeopener.
My biggest bugbear with the Linux console is that I can't scroll back any more. I definitely remember this used to work years ago. What happened to it?
I wish Linux framebuffer consoles would support sixels to do without X or wayland, mostly to have inline plots line https://github.com/csdvrx/sixel-gnuplot without having to use say fbi

This is possible on NetBSD: https://github.com/isaki68k/misc/blob/master/NetBSD/patch/x6...

Also, more and more terminals are getting Sixel support: https://www.arewesixelyet.com/

> On the other hand, text output to the console has generally gotten slower, usually much slower than you would expect for the change in console size

I don't see why we should tolerate slow rendering of text. Some of the techniques suggested by Casey Muratori (and recently used to accelerate text rendering in Windows Terminal) should also be usable in the framebuffer console.

(comment deleted)
If you want a fast text console, get an nvidia 7600GT or similar; they are the peak of text mode speed - using them at 160x60 on 1600x1200 is instant (that's with a high-res font,like ter-u20b).

Really ticks me off how the kernel is dropping stuff like scrollback for fast framebuffer devices, and since I got downvoted to hell the last time I said how slow and complicated certain finger-in-the-pie distros are making this area this time I'll post with a throw-away account.

I see no mention anywhere of yaft. Not an in-kernel framebuffer console, but one worth knowing about nonetheless, because it offers features like sixel support which probably won’t be landing in kernel any time soon.

[Also the title is ambiguous. While technically correct by referring to the kernel as Linux, I thought it originally meant GNU/Linux (the OS) because it didn’t say (e.g.) “consoles in the Linux kernel” or “consoles in GNU/Linux”]

Sixel is kind of a mess. Many of the newer terminals (kitty, mintty, wezterm, iterm2, et. al) have a special escape for directly sending a base64-encoded gif/png/jpeg to the terminal for rendering. More colors & more efficient.
The main advantage of sixel is probably the fact that it’s directly backward compatible with old DEC hardware, which I happen to like to use. I could have, say, a pdf reader that renders the pdf to the screen of an actual hardware VT330 by using sixels.
The question there would be, it has that advantage but at what cost?

I'm not incredibly familiar with sixels, but my basic understanding is that they're in a format that was convenient for use with dot matrix printers and were later adapted to terminal use with color support and such. This means that interacting with them is not going to be straightforward for developers familiar with any sort of modern graphics APIs on either the software or terminal ends.

If the main advantage is compatibility with old terminals that only really matter to a niche subset of retrocomputer enthusiasts I'd argue that any efforts to add graphics to the Linux terminal should be focused on a more modern design such as the base64-encoded images supported by a few terminals.

Since the article & the comment were about framebuffer terminals, in those cases, the base64 approach is superior: full color, built-in compression, no need to pre-rasterize. For <= 16 simultaneous colors (like in the original DEC terminals) sixel is A-OK, and in certain cases, even preferable! But when I see people today dither images to 256 colors just to be able to excrete them to a soft terminal with sixel, I cringe.

Something like Ascii85 or basE91 would have been even better, but beggars can't be choosers.

What is GNU and what is not these days? Is Wayland? Is GNOME?

Have you checked out Chimera Linux? Should I refer to that system as “the Linux kernel” or “GNU/Linux”? Neither makes sense.

Personally, I find it the most sane to understand that “Linux” is the name of the kernel and a “Linux Distribution” is a curated collection of software that runs on the Linux kernel. GNU Software may or may not be involved.

For me, the whole “GNU/Linux” things has always felt desperate. It is a bit like the 70’s BSD guys says AT&T needed to call their software BSD/UNIX because so many people used BSD stuff on their systems.

> What is GNU and what is not these days?

There is a definitive list: https://www.gnu.org/software/

> Is Wayland? Is GNOME?

Wayland never was. GNOME was at one point but isn’t any longer.

> Have you checked out Chimera Linux? Should I refer to that system as “the Linux kernel” or “GNU/Linux”? Neither makes sense.

Neither, but it would be both accurate and more specific to say that it is a Linux-based OS with BSD’s userland.

> whole “GNU/Linux” things has always felt desperate.

It’s now “desperate” to ask to receive credit for software you wrote? GNU wrote coreutils and gcc and early GNOME and those are part of pretty much any early GNU/Linux system and you think giving GNU credit for the work they put into building an OS is ‘desperate’?? No offense but screw that.

> It is a bit like the 70’s BSD guys says AT&T needed to call their software BSD/UNIX because so many people used BSD stuff on their systems.

But the BSD guys never said that..that I can tell. Unless you can provide specific examples, I can only assume this is a straw man and ignore it.