@cjd This sounds interesting, what would you use it for?
Now you can take it a little further: If the cost of running a thread is VERY SMALL, then you might go into the compiler and say: Lets take the "function call" idea and replace it with a thread_spawn followed by a wait_thread.
Instead of pushing out the entire belt to the stack and then jumping to a new function, lets spawn a thread for that function so it gets a fresh belt by definition and then we just wait (in our thread) for that function to complete.
Well now we get to ask ourselves: Do we need the result of that function RIGHT NOW, or can we continue processing without it? In many languages like C, you just do not know if you might rely on the side-effects of a function, but in languages like Rust or Haskell, you generally do...
So like:
for i in 0..100 { some_function(&object[i]); }
That could becomes entirely parallelized without the programmer lifting a finger...
- Function call -> Spawn child thread & wait
2. Branch (hardware implementation) -> Clone current thread as speculative sibling. Transition current thread to speculative sibling. Pending result, one of the two threads becomes non-speculative and the other one stops.
3. Interrupt -> Thread spawned by hardware
4. Syscall / IPC -> Spawn thread in other process memory space
5. Exception (e.g. div by zero or segfault) / signal -> Hardware stops thread, new thread spawned to handler
So basically every processor feature is a software implementation on top of the thread primitive. Speculative branching is more of a hardware implementation, you would just write a BRANCH instruction and a simple CPU would stall the thread until it has data to decide the branch. A complex one would hardware implement that using speculative mode and another thread...
@cjd This sounds really interesting
That change to the instruction set makes it possible to design some very aggressive optimizations in the hardware.
Right now you've got two kinds of hardware, CPUs and GPUs. A GPU can do like 10x the computation of a CPU, but it can't execute a whole lot of code. You need to say like "multiply these million numbers by those million numbers" and the GPU will shine...
A CPU can execute quite a bit of code quite quickly, but that all requires a whole lot of circuitry.
What I'm thinking is you build a single physical core of this architecture and it can have something like 128 belts, so you have 128 threads resident at any given time. But then you can also allocate some DRAM to enable 2048 belts that you can quickly swap in.
So then because your 128 belts are all asynchronous, you can basically package up computation requests and send them downstream as it they were network packets. And downstream you can put a GPU style "army of computation circuits" because now you have a nice convenient flow of computation requests for them to process.
So what you end up with is something like a wildly powerful CPU...