4 ms·
Caching is fine is there's no state involved. e.g: pure functions like the fibonacci sequence. As soon as your cache depends on a mutable state, things get rea
by fwip 4y ago
Caching is fine is there's no state involved. e.g: pure functions like the fibonacci sequence.
As soon as your cache depends on a mutable state, things get really hairy. Cache invalidation is one of the 2 hard problems in computer science, after all.
- hinkley 4y agoIf it's really no state it should be a compilation step. After watching some coworkers play keystone cops for 5 years I'm preparing to do just that to the last project they were responsible for. Their new project should have been that as well, but no it's going to be cache.
- PaulHoule 4y agoThis gives me flashbacks to Intel's great disaster of Itanium which seems so ridiculous in retrospect but I guess very few people understood superscalar processors in the 1990s. I did some serious thinking about processors that use the transport triggered architecture https://en.wikipedia.org/wiki/Transport_triggered_architecture https://en.wikipedia.org/wiki/Transport_triggered_architectu... which are a simple way to make a custom CPU (for the first time I thought, "I can make a custom CPU!") but do operations in lockstep in such a way that the whole thing blocks if a memory operation stalls. You might be able to get away with however because the TTA is meant to be codesigned with the code it runs on. Itanium was smarter than a TTA but it was predicated on the idea that a compiler could know how operations can be interleaved at run time. The compiler has no visibility into what gets cached, but at runtime the processor can opportunistically run operations that aren't stalled. For a general-purpose processor that's supposed to run general code, conventional superscalar processors do better than VLIW processors that require compilers to guess ahead of time what is impossible to guess.
- JonChesterfield 4y agoVLIW works _really_ well on a deterministic ISA. As in when you know how long a load is going to take at compile time because you know it's N clock cycles from that type of memory. Otherwise I really like the GPU derivative form where N instructions are ready to go and the hardware picks one where the prerequisite memory access has completed, despite that being variable.
- zasdffaa 4y ago> VLIW works _really_ well on a deterministic ISA that's a very good point. > Otherwise I really like the GPU derivative form where N instructions are ready to go and the hardware picks one where the prerequisite memory access has completed, despite that being variable Hmm, isn't that OOO (out of order) execution? And isn't that something GPUs explicitly don't do? (AFAIUI)
- JonChesterfield 4y agoI'm probably describing it poorly. A GPU (at least the AMD ones) has N execution units (of a few different types) and M threads (wavefronts) waiting to be scheduled onto them. Each cycle (ish), hardware picks one of the M threads, runs it for an instruction, suspends it again. Memory stalls / waits are handled by not scheduling the corresponding thread until it's ready. The operation might be a CAS over pcie so it's really variable in latency. Provided you have enough (ideally independent) work item / task / coroutine things available to enqueue, and you're designing for throughput instead of latency, that keeps the execution units or memory bandwidth fully occupied. Thus win. The x64 style model is deep pipeline + branch predict / speculation and it all goes slow when the guess fails. In contrast the GPU doesn't have to worry about guessing a branch destination incorrectly and unwinding wasted work. It does have to worry about having enough work queued up, and distribution of tasks across the compute unit / symmetric multiprocessor units, and the hardware-picks-the-order leaks into the concurrency model a bit.
- zasdffaa 4y agoNice clear answer, thanks.
- kaba0 4y agoWouldn’t this whole problem be solved by a graph-based architecture, used already by some compilers as an intermediate? Then the CPU sees where and when everything is needed and schedule the loading of registers as optimally as it is feasible, at runtime.