I JUST WANNA HAVE INTERFACES IN MY PROJECT, I GOTTA USE PYTHON SINCE I'M SCRIPTING FOR ITERM2, WHAT DO YOU MEAN I HAVE TO IMPORT THE ABILITY TO INTERFACE :kitty-cri-screm:
I JUST WANNA HAVE INTERFACES IN MY PROJECT, I GOTTA USE PYTHON SINCE I'M SCRIPTING FOR ITERM2, WHAT DO YOU MEAN I HAVE TO IMPORT THE ABILITY TO INTERFACE :kitty-cri-screm:
The old model
Short version
You have a CPU and a bunch of memory. The CPU has a program counter. It points to the memory address of the current instruction. The instruction gets loaded in. The CPU follows the instruction. And then depending on what the instruction was and how it went, it would either add one to the program counter or set it to a specific address (that’s called a jump).
Long version
You have:
You start up the machine, the program counter defaults to some preset value (usually 0x00). The instruction at the program counter is loaded into the CU. The CU decides what needs done. It could load something into a bus from memory, push some value into a register, instruction the ALU to add two registers together, etc. These are all system-specific possibilities and can vary pretty greatly.
The CU may take a different number of cycles depending on the instruction, but at the end of each instruction, it will either increment the program counter by 1 or it will jump to a specific address based on the outcome of the instruction. Some instructions will always result in a jump. Some never will. Some are conditional. That all depends on the machine you’re writing for.
This all repeats over and over until the instruction that gets loaded in is a halt instruction. And that’s it.
Cool videos to learn more
Stack and heap
The stack and the heap aren’t part of the modern complications that I mentioned and are way too old to say otherwise. However, if you go back to those old school personal computers, having dedicated stacks wasn’t always a given.
This StackOverflow post is a decent explanation of what they are and how they work.
Modern complications
It used to be that each instruction took a preset amount of clock cycles. But that would leave some modules doing absolutely nothing for extended periods of time. So instead, if a CPU could prove that, for example, a certain section of ALU code would run the same way no matter what the previous code did, it would run it early and let the ALU work on it while the previous code finished. And this worked even better if code wasn’t necessarily executed in the exact specified order, but instead in an equivalent order. This is the basis for pipelines.
Now, as people who maintained instruction sets grew their instruction sets over time, they found that it was often easier to, instead of create new circuitry for every single new instruction, just translate new instructions into a series of simpler old instructions. This would be slow to do with every instruction, but modern computers load a bunch of instructions at once and then cache their results. This whole situation is called microcode. Your instructions can technically get translated into an arbitrary set of largely undocumented instructions. Usually it’s nbd and makes things faster. Sometimes, it involves accusations of the NSA adding back doors into your encryption instructions.
Memory virtualization, I think, is an OS thing that I don’t super understand but it basically means that memory is no longer an index into the giant array of memory that is your RAM.
Memory locality and cache misses are things that affect speed. Basically, your CPU loads memory in chunks, so if you can store related memory close together, it will cut down on reads because those addresses will be in cache. This seems like a small detail, but it’s really hard to understand how much accounting for this can speed up your code.