1
$\begingroup$

For example on modern (32-64 bit CPUs), some sources say that manipulating a 32-bit or 64-bit integer will actually be faster than manipulating an 8-bit or 16-bit integer. This the reason for the (u)int_fastN_t types to be defined in C. Somehow the 8-bit instructions or 16-bit instructions are 'slower.'

Other sources say that loading a 16-bit number on a 32-bit machine would require a 32-bit load and a shift to extract the relevant bits. In the cast of having to shift, this would imply that some/all 16-bit instructions do not exist at all so they have to be emulated. (Because if, for example, a 16-bit load existed, this 32-bit load and shift would not be necessary).

But if they do, is there any reason why a CPU could not have opcodes for smaller sizes than the CPU native word size? And if they did is there any reason why they would be slower? If an 8-bit add instruction exists, why would the 8-bit adder circuit in the chip somehow be slower?

$\endgroup$

1 Answer 1

3
$\begingroup$

It depends entirely on the CPU. Adding an instruction costs transistors, as does making an instruction run faster, and those transistors then can't be used to improve the CPU in some other way.

As far as I know, the 8-bit adders on CPUs that support 8-bit addition are not any slower than 32-bit adders. The problem isn't the arithmetic operation but all of the bookkeeping that surrounds it: instruction decoding and scheduling and register management.

On x86, 16-bit instructions require a 1-byte prefix that 8- and 32-bit instructions don't, and I think that made 16-bit operations somewhat slower in the past, though I also think that difference has largely vanished on newer chips. Another problem with x86/x64 is that, for historical reasons, 8-bit and 16-bit operations leave the other bits of the 32-bit or 64-bit target register unchanged. That means in some cases the CPU has to wait for the previous instruction that wrote the register to finish in order to get the high bits, which limits parallelism. Older Intel CPUs, all the way back to the Pentium Pro in 1995, had fancier register tracking that avoided that problem, but newer CPUs have lost the ability. I don't know why, but it was probably to save transistors. For x64, AMD defined 32-bit instructions to clear the high 32 bits of the target register instead of preserving them, so 32-bit operations don't have this problem. They didn't change the behavior of the 8-bit and 16-bit instructions—probably to save transistors—so they are still slower on x64.

x86/x64 have no instructions that load or store less than 8 bits, so if you want to store 4- or 2-bit values space-efficiently you have to do it by hand. Some architectures bottom out at 32 bits instead, so 16- and 8-bit values have to be packed and unpacked by hand.

$\endgroup$
2
  • $\begingroup$ Here's something I don't understand: Why does the CPU have to wait for the previous 32-bit instruction to finish to access the 32 high bits of a register, or clear them? If the instruction is a 32-bit instruction anyway, then the high bits of the register are irrelevant and can be used for some other purpose. $\endgroup$
    – CPlus
    Dec 7, 2023 at 22:56
  • $\begingroup$ @user16217248 And you get into a hell of a lot of trouble because you have to keep track of which bits are valid. Consider an M1 processor with over 500 rename registers. $\endgroup$
    – gnasher729
    Dec 11, 2023 at 17:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.