In the year 2026, computers are used to do math. The type of math you use a computer for determines which computer you would prefer to use.
A different class of computer will accelerate specific types of operations for specific domains. The most classical optimization is providing dedicated floating units for floating point math. This avoids needing to manually issue shift instructions, logical instructions, some classes of clean up loops etc.
The point of engineering is to solve real problems for real people (and if possible, to be funny in how you do it). When a user wants to do something, you engineer a solution to enable them to do so. How you do it, and the contract you issue, is how the user will interact with that solution moving forward. You can modify contracts over time, so long as both parties are open to accepting those modifications and amending the contract. But for that to happen, both parties must be able to communicate.
Classically, when you start building hardware, you only get part of software’s inputs as a way to draw up the contract: namely the part that is also employed by the hardware maker. Over time, you end up with software that was built for your previous hardware to make up for this problem, but you inherit any and all of the concessions from said previous hardware.
The tragedy of an ISA happens when you try and embed architectural tricks that are relevant for one specific class of problem, at one specific point in time, so deep into the machine's contract that it becomes untenable to continue.
One way to make a lot of people happy is doing more work with less energy, &&/|| in less time. Typically this is referred to as amortization of an operation. Doing something always costs energy, be that executing the data, fetching it, sending it somewhere etc.
All computers have 3 phases to an operation: Fetch, Decode, Execute.
The cost of fetching an instruction is fixed*. No matter the type of instruction, the cost of loading it to memory, waiting on it to arrive, powering on an execution unit etc. costs power.
Likewise, Decoding an instruction is a mostly* fixed cost.
Execution can have drastically different costs depending on the operation. For arithmetic operators, Addition and Substractions are mostly very inexpensive. Multiplications are more expensive but reasonable, and division is particularly nasty. This holds both for in hardware area and generalized power consumption.
Every set of the above operators therefore has a globally fixed cost on fetch, globally fixed cost on decode, fixed cost on the type of execution, but variable depending on what you are requesting as an operation.
The trick: What if I could amortize the decode and fetch to an entire group of operations that all, themselves, would want to have the same operation executed?
To fetch that operation? Still the same as the base case. To decode that operation? still the same as the base case. Execution? N times the operation, which would be required no matter what.
If you want to have a contract, you need all parties to agree to what the various portions mean. For computers, that contract is the Instruction Set Architecture or ISA. That ISA can be openly documented like x86/Arm/RISC-V, it can be undocumented like in most accelerators, and their usage can be permissively licensed, commercially licensed, or flat out unavailable.
I have a simple goal: to build a clean, clear, ergonomic, modern SIMD extension for general purpose systems, be they as small as a microcontroller, a many core accelerator, or a super scalar, out of order processor.
Where this gets fun is the contracts and long term effects of an ISA. If you over specify operations, you limit design freedom to the point of never being able to innovate in hardware. In contrast, if you under specify, programs become weakly scoped. In a way, you can look at the spectrum of strong vs weakly specified languages, as well as strong vs weakly typed languages as an analogue.
Designing for the sake of designing helps no-one. Other posts and RFCs will discuss this, but the stated goal of these instructions is to act as a common substrate for hardware to build on top of.
Hardware can and will be used for different operations, to do different classes of maths.
A CPU, and more importantly a CPU programmer, tend to really like explicit predication/masking. But certain programming models such as the SIMT models most GPUs implement prefer implicit predication. The contract with the software programmer is that we enable them to do the type of mathematics they want, and act as a substrate to solve those problems. While the initial SIMD extensions aren't ment for Tensor Programming, they can of course support that model, the same way vector decomposition of tensors can be done.
DM's are open, I'm active in various communities such as Chips and Cheese, Ai Foundry amongst others. When in doubt, Twitter/mastodon/discord
Future topics of discussion:
Register sizes
Mask/predication Registers
Total element symmetry
minimum types with optional add ons vs guaranteed full classes of types
Guaranteed predication
encoding pressure in 32 bit opcode spaces
Universal rotation, shift and related instructions