13

The first version of the DEC Alpha had no load/store instructions for 8 or 16-bit values; if you wanted to deal with data of such sizes, you had to do it by shifting and masking values in registers as necessary. (This restriction was abandoned later because too much existing technology was designed around the assumption that addressing bytes is a commonplace thing to do; I'm asking purely about the technical reasons for doing it that way in the first version.)

On the face of it, it makes sense that it would simplify the hardware. According to http://alasir.com/articles/alpha_history/press/alpha_intro.html

Alpha is unconventional in the approach to byte manipulation. Single-byte stores found in conventional RISC architectures force cache and memory implementations to include byte shift-and-mask logic, and sequencer logic to perform read-modify-write on memory words. This approach is awkward to implement quickly, and tends to slow down cache access to normal 32- or 64-bit aligned quantities. It also makes it awkward to build a high-speed error-correcting write-back cache, which is often needed to keep a very fast RISC implementation busy. It also can make it difficult to pipeline multiple byte operations.

But hang on. Alpha did support storing 32-bit numbers. But it was a 64-bit architecture. So that's already supporting storing values smaller than a full word. Doesn't that already incur precisely the complexity that they were trying to avoid?

In other words, in a 64-bit CPU, isn't it pointless to refuse to support 8-bit stores if you are already supporting 32-bit stores that already need the same kind of hardware support? Or if not, why not?

  • 4
    I guess Alpha is still early in the RISC game so there's desire to make load/store hard wired logic to make them fast so simplicity is key. Right now everything is micro coded then you can easily create a slow path in micro code without impacting the fast path. – user3528438 Feb 24 at 17:14
  • 3
    Having 32-bit integer and float register arithmetic, as well as 64 bit, would have been weird if there were no 32-bit loads and stores. Using "64 bit for everything" often wastes half the RAM, which was also a scarce resource back then. – alephzero Feb 24 at 17:34
  • 2
    Another fun fact is that early ARM CPUs didn't have half-word (16 bit) load/store capability too, only bytes and (32bit) words were supported. en.wikichip.org/wiki/arm/armv1#load_instructions – lvd Feb 24 at 23:21
  • 2
    @lvd: I suspect the C Standard's rules about struct operations disturbing padding are designed to allow implementations to use 32-bit writes when updating 16-bit structure members that are followed by 16 bits of padding, without having to worry about whether another struct with a Common Initial Sequence might use the padding bits for some other purpose. – supercat Feb 24 at 23:34
  • 2
    @alephzero: And half the cache footprint and/or memory bandwidth, which are always scarce. – Peter Cordes Feb 25 at 8:04
12

Support for byte writes throughout a memory system is expensive. Among other things, if one wishes to use error-corrected memory that can correct single-bit errors, a memory that can be written in independent 8-bit chunks byte-writable memory will require four extra bits per octet, or 16 bits per 32-bit word. A memory that is limited to writing 16-bit chunks will require five bits extra per 16-bit word, or 10 bits per word; one that's limited to writing 32-bit chunks would only require six extra bits per word.

Worse, support for byte granularity increases the complexity of caching hardware. If one is using a 256-bit bus between the cache and main memory, limiting writes to multiples of 32 bits would require using eight read/write control circuits and keeping track of eight dirty bits per row. Allowing individual octets to be written would increase that to 32 separate read/write control circuits and 32 dirty bits.

For most tasks, having to use a read-modify-write sequence to update individual bytes would not be an issue. Unfortunately for DEC, many programming languages specify that adjacent bytes within any character array may be safely written by different threads without requiring synchronization, and offer no means by which programmers can indicate that they don't need such semantics. While the Alpha could efficiently process programs that wouldn't require it to accommodate the possibility of simultaneous writes to different parts of a word, languages provide no means of identifying such programs.

  • 1
    Are there 32 bytes in 256 bits? And why are 'dirty' bits needed per byte? Isn't it enough to have single 'dirty' bit for the whole cacheline? – lvd Feb 24 at 23:16
  • 1
    @lvd: Mea culpa on 32 vs 64. On a system with weak memory coherency (which is what I think Alpha uses), there is no effort to negotiate ownership of cache lines. If multiple cores write the same word of memory, there's no guarantee of who will win, but if two cores each write a different word in a cache line, and each core eventually commits all writes, and each core flushes its read cache after the other core commits writes, then memory should ultimately end up consistent. That will only work, though, if cores limit their write-back to the portions of the cache that they wrote themselves. – supercat Feb 24 at 23:30
  • 2
    To be fair, thread aware high-level-language memory models generally didn't appear until after first-gen Alpha was designed and released. Java was 1995, but IDK when the language added a thread-aware memory model. C/C++ wasn't formally until C11 / C++11, although it was widely understood as a de-facto standard before that. – Peter Cordes Feb 25 at 8:05
  • 3
    Related: Can modern x86 hardware not store a single byte to memory? - my answer covers other ISAs, including Alpha as the only(?) modern byte-addressable ISA without byte loads/stores, making it notable and interesting. Also Advantage of byte addressable memory over word addressable memory mentions L1d ECC overhead as one of Alpha's main reasons for no byte stores. – Peter Cordes Feb 25 at 8:07
  • 1
    Do you have more evidence about Alpha keeping per-word dirty status? Unless you RFO on a per-word basis, how can stores to the same line by different cores ensure ordering? Would memory barriers and atomic RMW operations have to flush to coherent L2 cache to make sure 2 cores weren't incrementing separate copies of the same word? If not, how could you get sequential consistency on Alpha with "weak coherency"? Linux managed to run on it, so I assume it was possible to write multi-threaded code for Alpha. I've only read about Alpha being as weak as C++11 (relaxed not consume) but coherent. – Peter Cordes Feb 25 at 8:11
11

Apart from anything else, Alpha was the VAX replacement - indeed, it was internally called EVAX. It would be necessary to take VMS source code written in VAX MACRO-32 assembler and compile it into Alpha machine code.

VMS had a lot of dependency on 32-bit words. MACRO-32 code was explicit about length. Higher-level code, in BLISS-32, tended to be explicit about operand length or perhaps merely assumed that a fullword was exactly 32 bits. Ergo, any credible hardware base for VMS requires efficient 32-bit operations.

I assume there was perceived to be no particular byte requirement for VMS since most (non-C) software would be using VMS conventions for strings (counted, not with a terminator character) and VAX machine instructions (MOVC3, CMPC3, etc., or the equivalent BLISS-32 'CH$' builtins), said instructions easily being emulated on Alpha. C was not seen as a major implementation language on VMS at the time.

(Warning: opinion of one DEC software guy only)

  • Which site, @another-dave? My father was an Alpha software guy at ZKO. – T.J.L. Feb 25 at 16:49
  • Various, most notably in REO, TW, and LKG. – another-dave Feb 25 at 17:48
  • VAX MACRO was mostly compiled to Alpha instructions. PALcode was only for the hairy stuff like INSQTI, which absolutely had to appear atomic. – richardb Feb 26 at 21:36
  • True, I'm not now sure what made me write the PALcode thing after the character-string instructions which would easily be implemented in normal Alpha code. I'll edit that out and forget I ever said it. Thanks. – another-dave Mar 3 at 3:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.