views:

195

answers:

7

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?

+8  A: 

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 :-)

paxdiablo
+1 for Tanenbaum, not because he's Tanenbaum, but because that book is seriously awesome.
bcat
There are few people in the industry that I rate as high as Tanenbaum (Knuth is the only one that springs immediately to mind). Both have contributed a great deal with their prolific books and software. I still have the 2/E of this book that I got back at Uni (a _looong_ time ago).
paxdiablo
Oh, I agree completely. I just meant that I like the book for its own worth, not just because its author is a very important figure in CS (which Tanenbaum certainly is). And yeah, I had to read the book in college as well, and I'm so glad my professor choose it over another computer systems book. I'm still amazed at how clearly it presents the material without dumbing it down in the least.
bcat
The cover makes it look like a Richard Scarry book. Judging by it's cover, I don't know if it's ... wait... I'm being told I shouldn't do that...
Dave Markle
+1  A: 

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.

hvgotcodes
+2  A: 

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.

Paul Nathan
+4  A: 

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.

rtperson
Upvoted for answering and providing further reading.
indyK1ng
A: 

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).

Michael Burr
+1  A: 

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.

KLee1
A: 

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.

Dave Markle