繁体   English   中英

优化整数和浮点乘法

[英]Optimize integer and floating point multiplication

我正在尝试优化以下操作,其中我有大量无符号短输入,需要按某个因子按比例缩小。 有没有办法优化它不使用浮点运算

unsigned short val = 65523U;
val = val * 0.943;

注意

我将在DSP上进行上述操作,其中浮点运算成本很高

最简单的方法是使用可以保存结果的32位类型:

uint16_t val = 65523U;
val = (uint_fast32_t)val * 943 / 1000;

或者,如果您想要更多类型的正确性和可移植性,同时允许编译器为任务使用最佳的整数类型:

#include <stdint.h>

uint_fast16_t val = UINT16_C(65523);
val = (uint_fast16_t) ( (uint_fast32_t)val * (uint_fast32_t)943 / (uint_fast32_t)1000 );

您可以乘以整数近似值0.943 * 2 ^ 16,然后除以2 ^ 16,编译器应将其转换为右移。 假设16位短路和至少32位整数:

val = ((unsigned)val * 61800) / 65536;

根据您的具体要求,您可以通过四舍五入到最接近的整数来获得更准确的结果:

val = ((unsigned)val * 61800 + 32768) / 65536;

任何其他两种力量都可以。 在64位平台上,您可以使用2 ^ 48来获得更高的精度。

多重/分裂的事情是好的。 但更好的是你可以避免分歧。

unisisned short的范围是0 ... 65535。

CPU中的所有数学计算都在内部处理为32位数。 但是在计算之后它们会被抛回到16位。 如果你将一个短数乘以一个大数,你想避免这种情况。 输出将很短,导致它截断该值。 所以我放置了强制转换来显示正在发生的事情,并确保编译器没有额外的类型转换。

unsigned short val = 65523U;

const unsigned int mult = 65536 * 0.943; // expressed as a fraction of 2^16

unsigned short output = (unsigned short)(((unsigned int)val * mult) >> 16));

因此,这会将值转换为32位无符号整数(以保证对类型的控制),根据原始分数将其乘以最多2 ^ 16,然后将其右移16,使其恢复到正确的比例。

你可以乘以943然后除以1000 你会保存一个浮点除法(但你要做乘法+一个欧几里德除法)。

unsigned short val = 65523U;
val = (val*943UL)/1000;

我得到: 61788

只要var*943unsigned long容量内( unsigned long long可用于进一步扩展限制),它就可以工作(即使在int为16位宽的系统上)。

你可以乘以943然后除以1000 你会保存一个浮点除法(但你要做乘法+一个欧几里德除法)。

unsigned short val = 65523U;
val = (val*943UL)/1000;

我得到: 61788

只要var*943unsigned long容量内( unsigned long long可用于进一步扩展限制),它就可以工作(即使在int为16位宽的系统上)。

编辑:你甚至可以避免除法计算比率乘以2的幂,我选择了16:

所以.943*(1<<16)61800.448

你可以做一次乘法和一次换班操作(非常快)。 此时使用unsigned long long更好,因为中间结果会变得非常大:

val = (val*61800UL)>>16;

得到大致相同的结果: 61787 使用61801 ,你得到61788

使用32位int或更高的平台,使用

int val = 65523U;
val = val * 943 / 1000;

很难被击败。 通过更改系数将截断转换为德语舍入。 如果你的系统有16位int那么你可以使用long (注意乘以943并除以1000将在long算术中发生)但是解决方案需要分析。

先划分1000会导致截断问题; 需要更大的类型来容纳更大的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM