Nightinggale wrote:I will write how I understand the plan, because I'm not sure I get it right. If I don't, then I will write this as suggestions because it sounds really useful and really cool.
Each CPU is handled individually. They are executed one at a time (Factorio is single threaded), but each has unique registers, meaning they each run independent from each other, though with shared memory. A CPU can specify where in the memory the registers should be stored and if multiple CPUs share the same location for registers, the second CPU will continue where the first finished, meaning they will act as one CPU with twice the number of cycles each tick.
The location of registers is a memory slot in itself, meaning it can be overwritten. Say there is a setup with 7 CPUs. The first one checks if aliens are on radar (attacking) and if that's the case, assign the remaining CPUs to all share the same location for registers. The rest will then be a powerful CPU to deal with defenses (like moving tanks into position). If no aliens are on radar, the other CPUs are switched back to do their normal tasks. In other words being attacked triggers an interrupt.
That exactly the plan, and more, the CPU status relly itself on a register so if the register say that the given CPU is halted, then it is, if it remove the halt status, then the CPU woke, also as you said, a CPU could be reasigned to another task by moving his registers, it simply need to have theirs registers moved first because by default, the CPU use his own registers and then use them to say their are moved, so the default register could point to different registers depending of the needed use. Also it's not just move the registers, there is in fact 4 commands, move all registers, move status register, move control register, move main register, so you can for example have seven CPU that shared their control pointers but not their status and main register, which can be powerful in some cases
Nightinggale wrote:
CPU execution order isn't mentioned, but it would be nice to have them execute in the same order as address space. I can think of cases where it could be useful information, even though it often likely won't matter at all.
CPU execution is in the address space order.
Nightinggale wrote:
Sleep X ticks would really need to be that, not just halt until the next CPU if multiple CPUs share the same registers.
In fact yield (sleep X ticks) is about making a CPU sleep X ticks, if CPUs share their status registers, they all wait for the next tick as soon as one instruction said so.
Nightinggale wrote:
y.petremann wrote:Basicaly ... no ! it add more confusion because with this architechture, it would be frequent to use CPU that need to access things, instead I think that the local space mode for the address module would be more insteresting because to would let to bundle a complete address space inside it, local space could be used in two ways: CPU space would let to have a local space bound to the current CPU and RAM local space would let to have a local space bound to the current instruction module.
So you are saying that a CPU has a register, which is a pointer to an address module. An address module can then make a local address space out of the global by combining up to 4 rows of local memory. If you add modules and change the memory layout, updating the address module will fix everything because instructions will be set relative to the setup in the address module.
Not really, The address module would rebound all address, but is a CPU has his register (original or pointed) to a local space defined by an address module, then it can use that local space, but yeah the address modules would help fix everything, local space or not. Local space would simply help with some cases where about 8 CPUs use the same program but don't process the same data.
Nightinggale wrote:
Sounds interesting, but not without issues. What if the player makes one chunk of ROM, which is coded to be in one address module and then later add another one, which is in another address module. This involves two problems: how to call the function in the other module and wouldn't that result in ever changing the active address module? And what if there is one address module for the ROM with the code and another one for the RAM with input and output?
The fact is that Address Modules would not be used as ROM or RAM because they would modify the structure of the grid everytime, They need to be used to move other modules address space, they can even move their own address space.
In fact letting the process modifying the address module is the point, but their is a functionnality not yet documented : ROM, Connector and Address Module are read only by program if disabled, Connectors are Writen by circuit network depending of signal the user want.
And finally, there is two type of rebound of address space, global and local, global rebound would rebound completely for the complete grid, local would simply add a sort of proxy of what you need to specific address, so wherever you placed your CPU, you can rebound them to be considered at 0, so each CPU with local space could use 0 to 16 to access their registers, but also their real address, simply think that defining a local address space would push addresses and reserve that space for local space, defining another local space at the same address but bigger, would simply expand that local space so that each space could fit inside.
Nightinggale wrote:
It could be interesting to add a label instruction (which is essentially just a no operation if executed). #V would then be the label ID. This would allow a instruction to jump to label ID #V. That would be really useful if combined with relative jumps since this will make function calls ignore the issue of which address they reside in. This would remove the need to make an address space for instructions, though it would be nice to get some sort of assistance in figuring out where a relative jump ends up. Not sure how to make that.
Next a CPU can get a local address space where data is stored from 33-160 (or whatever else you would want). This range will then be the only space where absolute addresses will be needed. Instructions then comes in the high range, but we don't really care about the addresses for those, because they will be all relative and label based.
That quite hard to do that way because it would need a full memory search done in the mod and not by program which result in bad performances, instead the solution would be to do some sort of call map in the ram, so you could call not by direct address but by a pointer which could be interesting because you could add a blueprinted CPU that would scan entire memory for a specific pattern like wood item signal and then report their address in a specific memory space containing pointers.
Also in real asm, labels don't exists ... everything is ... data, program is data, and when a program call another, it simply jump (call) to the address. Labels would definitely be a thing, like any other cool feature, but not inside the controllers, more inside a higher level language that peoples would compile to get the blueprint and then use.
Nightinggale wrote:
General considerations
Power usage:
ROM should use way less power than RAM, if ROM use any at all. People should be encouraged to consider if they need ROM or RAM.
Yeah, in fact to report this, I made so that to write a value, you need to read it before. A read only module would refuse to write and thus consume write power. using CPU memory consume less power.
Nightinggale wrote:
CPUs could be power hungry, though power usage should depend on how many cycles are used each tick, meaning making a CPU sleep or halt should result in a low power standby. People should be encourage to figure out how to use as few CPUs as possible for other reasons than just lag while at the same time not be so restrictive that you can't add a hundred CPUs and make something brilliant if the computer can handle it.
Yeah definitively a a point too, I've just not balanced this yet, and for now the mod is quite power hungry, I've got pretty bad results, for now about performance, and I think it can be definitively better but there is a lot of optimisations to do.
Nightinggale wrote:
It would be useful with multiple general purpose registers, say R1-R4. This will allow more complex instructions, which can take multiple arguments. Since each instruction has only one #V, it would be a matter of filling up the registers and then call the instruction, which reads them as input. It could also allow making instructions with multiple outputs. This seems quite important when considering that you want to encourage other people to release addon mods with additional instructions.
Will definitivelly add general purpose registers, I think for a total of 8 documented registers, in fact they are already there since memory and registers are not so different, it's just that no instruction use these memory slots as registers.