___SMMUL(inlet_a<<3,inlet_b<<2) input confusion

Hi,

Could someone explain why the inlet_a is <<3 and inlet_b is <<2 please?

I was looking at the k-rate/k-rate, s-rate/k-rate and k-rate/s-rate variants of math/*, and I can seem to understand why the inputs are needed to be multiply bit-shifted by different amounts?

Is this to return a better resolution of 32-bit number?

I’m pretty sketchy on bit-shifting but it’s starting to make sense!

Cheers

1 Like

What’s important is that the result gets shifted 5 positions to the left. You could also shift a<<2 and b<<3, or a<<1 and b<<4, and so on, as long as the sum of all the shifting is 5.

However it seems good practice to left-shift as few slots as possible per variable, so that we don’t clip stuff, which is why the shifty business is spread as equally as possible over both.

You may have seen somewhere that Axoloti uses the “Q27” format for its k-rate and a-rate variables. It’s complex, but in essence it means 27 bits (0x0800_0000) are the maximum (which equals 64.0 in the patcher. Actually the positive maximum is 0x07FF_FFFF because signed integers — but that’s another story.)

So anyway: 27 + 5 is 32.
And ___SMMUL() will treat the full 32 bits as “times one”, which makes it so fast and convenient. Meaning if you multiplied 0xFFFF_FFFF with 0xFFFF_FFFF, the result would be 0xFFFF_FFFF.

One times one equals one. Again, let’s ignore the signed bit in signed integers for now.

Check out this little patch:

smmul_bitshift.axp (5.2 KB)

You can see that in the embedded simple_mult object, we just __SMMUL the naked inputs together without shifting, then shift the result back up externally with the << object. And it turns out we get more error in the result - 0x07FF_FFE0 via simple_mult VS. 0x07FF_FFFE via math/*!

This is why it also makes sense to first left-shift the input variables while passing them to the SMMUL, so that we use as high a resolution as possible for the multiplication.

(Bonus info: Another, negligible reason is that many of the ARM instructions are able to shift their input values in the same CPU cycle as the instruction itself is running, so the CPU is not wasting cycles by first creating shifted copies of variables, then running them through SMMUL. Actually not sure if SMMUL one of the instructions that can do this, but it might.)

1 Like

Thanks for the detail here - I will dig into this later when I have time/space :pray: to absorb!

Got it! this makes sense now

1 Like