我想在24位dsp上移植32位32位无符号乘法(它是线性同余生成器,所以我不允许截断,我也不想用24位替换当前的LCG)。可用的数据类型是24和48位整数。
仅需要最后32个LSB。你知道有什么黑客可以通过比常规方式更少的乘法,掩码和班次来实现它吗?
这条线看起来像这样:
//val is an int(32 bit)
val = (1664525 * val) + 1013904223;
答案 0 :(得分:0)
大纲(以我当前的编译器风格):
static uint48_t val = SEED;
...
val = 0xFFFFFFFFUL & ((1664525UL * val) + 1013904223UL);
希望编译器能够识别:
注意强> 如果你将系数放大2 ^ 16,你可以免费截断,但由于缺乏信息 你必须探索/决定它是否总体上更好。
答案 1 :(得分:0)
(这更详细说明为什么两个乘法24×24
→n,31< n足够32×32→min(n,40)。)
这个问题很少披露构建方法的能力
32×21→32 in fewer [24×24] multiplies, masks and shifts than the usual way
on:
24 and 48 bit ints
& DSP
(我读过高吞吐量,非高延迟24×24→48
)。
至于确实 24×24→48 乘以(甚至 24×24 + 56→56 MAC)和一个因子小于24位,问题毫无意义,第二个倍增是引人注目的解决方案。
24
那么,是否可以仅使用第二个 24×24→48 来生成“长产品”?
设(的字节)因子分别为 w_xyz 和 W_XYZ ;下划线表明,如果解释为24位整数,则“ W s”是较高有效字/ int中的较低有效位。第一个 24×24→48 给出了总和
的 ZX 强>
ÿ的 XZY 强>
XX的 YYZZ 强>
X的 YYZ
xZ ,需要什么(胖)是
w Z +
ž的 w ^ 即可。
这可以使用一个组合乘法来计算
((w <&lt; 16)|(z&amp; 0xff))×((W <&lt; 16)|(Z&amp; 0xff))。 (别担心wZ + zW的第17位“跑”到wW。)
(在这个答案的第一个版本中,我愚蠢地分别制作了 wZ 和 zW - 无论如何,他们的总和最终是想要的。)
(令人讨厌的是,这就是 24×24→24 作为基本操作所能做的一切 - 除了“组合乘法”之外,你需要四个而不是一个。 )
另一个值得探索的角度是选择不同的PRNG。 可能必须> 24位(告诉!) 在24位机器上,XorShift* (or even XorShift+) 48/32似乎值得一看。