3 ms·
I remember developing for the PS back in 1996-1999. The first title I worked on I was building the graphics engine and animation systems. Originally in C, the
by louthy 7y ago
I remember developing for the PS back in 1996-1999. The first title I worked on I was building the graphics engine and animation systems. Originally in C, then in MIPS assembler to get as much perf as possible: with a fixed target the difference for your title would be mostly down to the performance of the graphics engine.
I got to the point where I'd fitted the entire graphics engine and animation system into 4K, so it would fit in the instruction cache, and moved as much regularly used data into the 1K scratchpad as I could fit (Yes, an L1 cache that you decided manually what to put in it!). Access to the scratchpad would take 1 cycle.
Then I'd 'hand interleave' asm operations. Reading from memory was slow, it took 4 cycles, which normally would be filled with NOPs by the C compiler (1 load instruction, 3 NOPs). So, I'd use assembly instead of C and try to fill those NOPs with other actual operations that didn't need the memory being requested, essentially doing hand-crafted concurrency.
Because loading and storing from/to memory was such a common operation, this would make the code very, very hard to maintain, and sent me slightly crazy for a while! Often it meant doing x, y, z operations (for 3D processing, like vector multiplication) concurrently, but wherever the the NOPs could be reduced, more could be done.
With various other bits of cunning I eventually got it to the point where I broke the manufacturers specs for whatever Sony said the PS could do per-second (memory is a bit fuzzy about what those specs were, but I remember myself and the team being pretty damn pleased at the time).
It was a fun machine to program for. The Saturn which was out at the same time always struggled to keep up because it was so hard to develop for, even though on paper it was better. I think that was what struck the death knell for Sega.
- pcwalton 7y ago> Reading from memory was slow, it took 4 cycles, which normally would be filled with NOPs by the C compiler (1 load instruction, 3 NOPs). So, I'd use assembly instead of C and try to fill those NOPs with other actual operations that didn't need the memory being requested, essentially doing hand-crafted concurrency. This isn't usual for the MIPS ISA, is it? MIPS has branch delay slots but not memory delay slots, per my understanding. (Of course if there's a data dependency on a pending load the CPU still has to stall.)
- louthy 7y agoThe R3000 suffered from the need for load delay slots too, unfortunately. I may have forgotten all the exact details though. I am genuinely in awe of people who seem to retain the details of this stuff 10 - 20 years later, my brain certainly doesn't work like that!
- AtlasBarfed 7y agoThe current AMD chips have 1.5MB of LEVEL 1 CACHE! To say nothing of the 8MB L2, 32MB L3, and the integrated video processor. And you had to do the work that an optimizing compiler could do today, although they have to target a "theoretical" CPU rather than a fixed hardware set like the old consoles. Since all the superscalar tricks such as out of order, spec exec, and the like are now maxed out, maybe what should happen is that CPU vendors should concentrate on optimizing a fixed VM-sized hardware profile that the compilers can more efficiently target. A CPU ISA is somewhat like that, but it has so much variance. With Moore's law gone, we will actually have to start removing abstraction from the development pipeline and get to more optimized and direct code to drive performance.