簡體   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