计算机如何只使用几个寄存器?

发布于 2024-09-13 14:45:22 字数 71 浏览 2 评论 0原文

我对汇编了解一点,通用寄存器有 4 到 8 个左右。计算机上的所有程序如何使用这么多的寄存器来工作,特别是多线程和其他所有程序?

I know a little about assembly, and that there are 4 or 8 or so general purpose registers. How do all the programs on a computer work with just that amount of registers, especially with multithreading and everything?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

春夜浅 2024-09-20 14:45:22

多线程本身并不影响正在使用的寄存器数量。当一个线程被换出时,它通常会将其寄存器保存到内存中,并且下一个要运行的线程会从之前的保存中加载这些寄存器。

一个示例是具有线程控制块结构(TCB)的系统。该结构将包含(当线程未运行时)保存的指令指针、堆栈指针、通用寄存器、浮点寄存器、线程统计信息等。简而言之,需要做的一切工作才能将线程完全恢复到被换出另一个线程运行时的状态。

并不是计算机中发生的所有事情都是在寄存器中完成的。现代编译器可以优化代码,以便将最常用的数据项保存在寄存器中,但绝大多数数据保存在内存中,仅在需要时才购买到寄存器中。

我读过的关于这个主题的最好的书是 Tanenbaum 的 "结构化计算机组织" 从数字逻辑层到操作系统级别,每个级别都建立在前一个级别之上。

        替代文字

旁白:我的梦想是有一天写一本像这样的书,涵盖从夸克级到 Emacs 的一切:-)

Multi-threading itself doesn't affect the number of registers in use. When a thread is swapped out, it generally has its registers saved to memory and the next thread to run has those registers loaded up from its previous save.

An example is a system having a thread control block structure (TCB). This structure would contain (while the thread wasn't running), the saved instruction pointer, stack pointer, general purpose registers, floating point registers, thread statistics and so on. In short, everything needed to totally restore the thread to the state it was in when it was swapped out for another thread to run.

And not everything that goes on in a computer is done in registers. Modern compilers can optimise code so that the data items used the most are kept in registers but the vast majority of data is held in memory and only bought into registers when needed.

The best book I've ever read on the subject is Tanenbaum's "Structured Computer Organization" which examines computers in terms of layers, from the digital logic level up to the operating system level, with each level building on the previous.

           alt text

Aside: my dream is to one day write a book just like this that covers everything, from the quark level up to Emacs :-)

夜巴黎 2024-09-20 14:45:22

其他变量和线程堆栈通常存储在受保护的内存空间中,需要时可以将它们调用到寄存器中。

您可能需要查看计算系统的要素一书以更好地理解了解计算机 CPU 的工作原理。本书由一系列项目组成,您可以从 NAND 门到 CPU、汇编器、简单编译器,再到小型操作系统。这对于了解计算机所有部件如何组合在一起非常有价值。

The other variables and thread stacks are usually stored in protected memory space, where they can be called into registers when needed.

You may want to check out the book The Elements of Computing Systems for a good understanding of how your computer's CPU works. The book is set up as a series of projects where you work up from a NAND gate to a CPU, assembler, simple compiler, and on to a small operating system. It's invaluable in understanding how all your computer's parts fit together.

烟燃烟灭 2024-09-20 14:45:22

每次线程(或进程)换出时,所有寄存器都会被操作系统内核压入堆栈,放入通常称为进程控制块的数据结构中。然后,当线程/进程换回时,将从 PCB 读取寄存器的数据并将其从堆栈弹出到寄存器。


还有内部寄存器和映射表,x86 内部设置了一个虚拟寄存器表来保留 IA32 指令集架构,同时具有更大的灵活性来设计超标量架构和复杂的指令调度算法。

此外,指令集通常有加载存储指令,它们与指向内存的指针结合使用,允许将数据从寄存器存储到内存中。这就是术语“加载-存储机器”的由来,即没有直接在内存上操作的指令的计算机。

有些计算机确实有对内存进行操作的指令;有些是基于堆栈的。这取决于设计者和硬件上的限制。

Each time a thread (or a process) swaps out, all the registers are pushed onto the stack by the operating system kernel into a data structure usually called the Process Control Block. Then, when the thread/process swaps back in, the register's data are read from PCB and popped off the stack to the registers.


There are also internal registers and a mapping table that the x86 has internally that sort of set up a virtual register table to preserve the IA32 instruction set architecture while having a greater flexibility to design superscalar architectures and sophisticated instruction scheduling algorithms.

Also, instruction sets usually have a load and store instruction, which is used in conjunction with pointers to memory, allowing data to be stored from registers into memory. Which is where the term Load-Store machine comes from, ie, a computer that doesn't have instructions that operate directly on memory.

Some computers do have instructions that operate on memory; some are stack-based. It depends on the designers and the constraints being placed on the hardware.

坏尐絯℡ 2024-09-20 14:45:22

您必须意识到,即使是简单的事情也会执行数千到数百万条汇编指令。这些寄存器的值经常交换。

you have to realize that thousands to millions of assembly instructions get executed for even simple things. Those registers are getting their values swapped often.

街角卖回忆 2024-09-20 14:45:22

实际上非常有趣的是计算机如何能够使用如此少的寄存器来完成它所做的一切。

这是非常聪明的汇编级编程(通常是由于非常聪明的编译器),允许如此有效地使用如此少的寄存器。

如果仅使用提供的少数寄存器无法完成问题,则程序通常会将其寄存器“溢出”到主内存堆栈中。通过记住我们将溢出的寄存器放在堆栈上的位置,我们可以轻松地检索它们。

当我们用完所需的寄存器时,我们只需将它们存储在堆栈中,这为我们提供了比大多数程序所需的空间。

在多线程的特定情况下,我们只需将所有寄存器保存到内存中,然后我们就可以为其他线程提供一个干净的状态。

It is actually pretty interesting how the computer is capable of using so few registers to accomplish everything that it does.

It is really clever programming at the assembly level (typically due to terrifically clever compilers) that allow so few registers to be used so efficiently.

If a problem is impossible to complete with only the few registers provided, the program will typically "spill" its registers into the main memory stack. By remembering where on the stack we put our spilled registers we can easily retrieve them back.

When we run out of the registers we need we simply store them on the stack, which gives us FAR more space than most of us need for our programs.

In the specific case of multi-threading, we just save all of our registers to memory, then we have a clean slate for the other threads.

乙白 2024-09-20 14:45:22

这是计算机其他存储(尤其是 RAM)的用途之一:在寄存器中保存和恢复数据位。

当一个线程被切换出去以便另一个线程可以运行时。第一个线程的寄存器状态保存在某个地方(在堆栈或其他数据结构上),第二个线程的寄存器状态从之前保存的位置恢复。 RAM 的速度足够快,可以在一秒钟内发生数千次这样的切换,但需要足够的时间,如果您不必要地交换线程,可能会影响性能。

另一个非常非常常见的情况是局部变量 - 如果局部变量使用的时间足够短,它可能永远不会存在于寄存器之外。但是,在许多情况下,可能需要将局部变量从寄存器保存到内存位置,以便可以将其他值加载到寄存器中并在寄存器中进行操作。实际上,几乎所有变量都会发生同样的情况,而不仅仅是局部变量(但局部变量更有可能永远不会存在于内存中)。

That's one of the things that the computer's other storage, particularly RAM, is used for: to save and restore bits of data in and out of registers.

When a thread is switched away so another thread can run. the first threads register state is saved somewhere (on the stack or some other data structure), and the seconds thread's register state is restored from wherever it was saved before. RAM is fast enough that thousands of these switches can occur in a second, but takes enough time that if you're swapping threads needlessly it can impact performance.

Another very, very common occurrence is local variables - if a local variable is used for a short enough period of time, it may never exist outside of a register. however, in many cases, a local variable might need to be saved from the register to a memory location so some other value can be loaded into and manipulated in a register. The same actually happens for pretty much any variables, not just locals (but it's much more likely for a local to never have an existence in memory).

坠似风落 2024-09-20 14:45:22

这是一个非常复杂的问题,答案取决于您的 CPU 架构。

在过去的好日子里,你是对的——确实只有一些通用寄存器。现在,CPU和编译器玩的是“三张牌蒙特”的游戏通过诸如寄存器重命名之类的技术来使用通用寄存器。

尽管在简单的体系结构上,当发生上下文切换时,寄存器确实会被复制到[缓存]内存,但诸如 SMT“愚弄”操作系统,使其认为内核数量比实际数量多。

但对您的问题最普遍的答案是,数据被移入和移出寄存器很多。这就是为什么您在任何给定的汇编程序中看到的大量指令都是“MOV”指令。 CPU 和编译器设计者花费大量时间和金钱来优化他们的设计,这样你就不会将数据从主内存(缓慢)移动到寄存器中——他们试图尽可能多地缓存数据。如此大量的“MOV”指令就是为什么内存延迟和总线速度对于整个计算机的性能如此重要的原因。

That's a pretty involved question and the answer depends on your CPU architecture.

In the good ol' days, you were right -- there were indeed just a few general purpose registers. Nowadays, the CPU and the compiler plays a game of "three-card-monte" with your general purpose registers through techniques like register renaming.

Though on simple architectures it is true that registers get copied to [cache] memory when a context-switch happens, techniques like SMT "fool" the OS into thinking there are more cores than they actually are.

But the most general answer to your question is that data is moved into and out of registers a lot. And that's why a great deal of the instructions you see in any given assembly program is are "MOV" instructions. CPU and compiler designers spend a lot of time and money optimizing their designs so that you aren't MOVing data from main memory (slow) into registers -- they try to keep data cached as much as possible. This large number of "MOV" instructions is why memory latency and bus speed are so crucial to the performance of the overall computer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文