Path: utzoo!attcan!uunet!seismo!sundc!pitstop!sun!amdahl!amdcad!rpw3 From: rpw3@amdcad.AMD.COM (Rob Warnock) Newsgroups: comp.arch Subject: Re: Are all RISCs the same? Message-ID: <22890@amdcad.AMD.COM> Date: 10 Sep 88 07:17:52 GMT References: <58@zeno.MN.ORG> <6903@aw.sei.cmu.edu> <22860@amdcad.AMD.COM> <6930@aw.sei.cmu.edu> Reply-To: rpw3@amdcad.UUCP (Rob Warnock) Organization: [Consultant] San Mateo, CA Lines: 57 In article <6930@aw.sei.cmu.edu> firth@bd.sei.cmu.edu (Robert Firth) writes: +--------------- | Even without a parallel register set, you can go a long way by reserving a | couple of general registers for the "in and out" interrupt handlers. If, | of course, your compiler cooperates. But using the normal register window | for interrupts seems crazy: if the interrupt occurs at the wrong call depth | (1/4 of the time, say) then responding to it will take several times as | long, since 128 (or whatever) registers will be spilled to give it a | window of 32, of which it might use 4. This is negative leverage with a | vengeance! +--------------- Well, I don't know what machine you have in mind, but for the Am29000 (which has 128 "local" registers) it doesn't work that way. The 29k has completely *variable*-sized register windows, and you spill exactly what is needed. Thus, an interrupt sequence which uses 4 local registers will spill/fill (save/restore) exactly 4 of them, and an interrupt sequence which uses 37 registers (because of subroutine call depth or whatever) will save/restore exactly 37. It is important to note that because of the variable window size, for normal subroutine calls fills are *not* paired dynamically with spills, but occur only when needed, giving a 128-word "hysteresis" in the spilling and filling. The same is almost true for interrupts, except that on returning from an interrupt you must do a final fill at the end which restores the register file to the state it had on entry. (As it turns out, this is automatic due to a trick in the way the registers are set up on entry to the interrupt. Details posted upon request...) *As an optimization*, the software designer may choose to explicitly pre-spill some number of registers on every interrupt, thus trading off the costs of the explicit save/restore versus the slightly higher overhead of the implicit spill/fill mechanism when only a small number of registers is needed. This pre-spill is not mandated by the hardware, but is something you might do while tuning a completed system. It decreases the average interrupt overhead, leaves worst-case the same, and may [or may not -- it depends] slightly increase the minimum overhead. (The same tuning can be applied to system calls, if desired, and both forms have been used in the System-V and 4.3 ports to the 29000.) While a large register file *does* increase full context-switch time somewhat (but not as badly as you might fear, given that you have load/store-multiple instructions and burst-capable memories), a variable-sized register window such as used in the Am29000 (similar to the original Berkeley RISC's registers) can provide *excellent* interrupt and subroutine-call performance, enough so to more than make up for the increased context-switch time. This also does mean that it is better to run critical real-time code as an interrupt rather than as a heavy-weight process, ...but this has always been true. Rob Warnock Systems Architecture Consultant UUCP: {amdcad,fortune,sun}!redwood!rpw3 ATTmail: !rpw3 DDD: (415)572-2607 USPS: 627 26th Ave, San Mateo, CA 94403