我对汇编有一点了解,并且有4个或8个左右的通用寄存器。计算机上的所有程序如何使用这些寄存器,特别是多线程和所有程序?
答案 0 :(得分:11)
多线程本身不会影响正在使用的寄存器数量。当一个线程被换出时,它通常将其寄存器保存到内存中,下一个要运行的线程将这些寄存器从之前的保存中加载起来。
一个例子是具有线程控制块结构(TCB)的系统。此结构将包含(当线程未运行时),保存的指令指针,堆栈指针,通用寄存器,浮点寄存器,线程统计信息等。简而言之,一切都需要将线程完全恢复到换掉另一个线程运行时所处的状态。
并非计算机中发生的一切都是在寄存器中完成的。现代编译器可以优化代码,使得使用最多的数据项保存在寄存器中,但绝大多数数据都保存在内存中,只在需要时才被买入寄存器。
我读过的关于这个主题的最好的书是Tanenbaum's "Structured Computer Organization",它从层次上检查计算机,从数字逻辑级到操作系统级,每个级别都建立在以前的。
alt text http://ecx.images-amazon.com/images/I/51PAGENX36L._SL500_AA300_.jpg
除了:我的梦想是有一天写一本涵盖所有的书,从夸克级别到Emacs: - )
答案 1 :(得分:5)
其他变量和线程堆栈通常存储在受保护的存储空间中,在需要时可以将它们调用到寄存器中。
您可能需要查看书籍The Elements of Computing Systems,以便更好地了解计算机CPU的工作原理。本书设置为一系列项目,您可以从NAND门到CPU,汇编程序,简单编译器以及小型操作系统进行操作。它非常有助于理解所有计算机的所有部件是如何组合在一起的。
答案 2 :(得分:2)
每次线程(或进程)交换时,操作系统内核将所有寄存器压入堆栈,通常称为过程控制块。然后,当线程/进程重新插入时,寄存器的数据从PCB读取并从堆栈弹出到寄存器。
还有内部寄存器和x86内部的映射表,它们设置了一个虚拟寄存器表来保留IA32指令集架构,同时具有更大的灵活性来设计超标量体系结构和复杂的指令调度算法。
此外,指令集通常具有 load 和 store 指令,该指令与指向内存的指针结合使用,允许将数据从寄存器存储到内存中。这就是Load-Store机器这个术语的来源,即没有直接在内存上运行的指令的计算机。
有些计算机确实有对内存进行操作的指令;有些是基于堆栈的。这取决于设计者和硬件上的限制。
答案 3 :(得分:1)
你必须意识到即使是简单的事情,也会执行数千到数百万的汇编指令。这些寄存器经常交换它们的值。
答案 4 :(得分:1)
实际上,计算机能够使用如此少的寄存器来完成它所做的一切非常有趣。
在汇编级别进行非常聪明的编程(通常是由于非常聪明的编译器),这样可以很有效地使用这么少的寄存器。
如果只提供少量寄存器就无法完成问题,程序通常会将其寄存器“溢出”到主存储器堆栈中。通过记住堆栈中我们放置溢出寄存器的位置,我们可以轻松地将它们检索回来。
当我们用完寄存器时,我们只需将它们存储在堆栈中,这使我们 FAR 的空间比我们大多数程序所需的空间更多。
在多线程的特定情况下,我们只是将所有寄存器保存到内存中,然后我们为其他线程提供了一个干净的平板。
答案 5 :(得分:0)
这是计算机的其他存储器(尤其是RAM)用于以下操作之一:在寄存器中保存和恢复数据位。
当线程被切换时,另一个线程可以运行。第一个线程寄存器状态保存在某处(在堆栈或其他一些数据结构上),并且秒线程的寄存器状态从以前保存的任何地方恢复。 RAM足够快,可以在一秒钟内发生数千个这样的交换机,但是如果你不必要地交换线程就会花费足够的时间来影响性能。
另一个非常常见的情况是局部变量 - 如果局部变量在足够短的时间内使用,它可能永远不会存在于寄存器之外。但是,在许多情况下,可能需要将本地变量从寄存器保存到存储器位置,以便可以在寄存器中加载和操作某些其他值。几乎任何变量都会发生同样的事情,而不仅仅是本地人(但是本地更不可能在内存中存在)。
答案 6 :(得分:0)
这是一个非常复杂的问题,答案取决于您的CPU架构。
在美好的时代,你是对的 - 确实只有几个通用寄存器。如今,CPU和编译器通过诸如three-card-monte之类的技术与您的通用寄存器一起玩“register renaming”游戏。
虽然在简单的体系结构中,当上下文切换发生时,寄存器被复制到[cache]内存是正确的,像SMT这样的技术“愚弄”操作系统,认为有更多的内核而不是实际的内核。 / p>
但是对你的问题最常见的答案是数据被移入和移出寄存器很多。这就是为什么在任何给定的汇编程序中看到的大量指令都是“MOV”指令。 CPU和编译器设计人员花费大量时间和金钱来优化他们的设计,这样您就不会将数据从主存储器(慢速)移动到寄存器中 - 他们会尽可能地保持数据缓存。大量的“MOV”指令是内存延迟和总线速度对整个计算机性能至关重要的原因。