我有這行代碼:如何使用位操作來取代modulu和division操作符?
base_num = (arr[j]/base)%256;
這條線在循環運行和操作「/」和「%」採取了大量的資源和時間來執行的。我想改變這一行並應用位操作以最大化程序性能。我怎樣才能做到這一點?
謝謝。
我有這行代碼:如何使用位操作來取代modulu和division操作符?
base_num = (arr[j]/base)%256;
這條線在循環運行和操作「/」和「%」採取了大量的資源和時間來執行的。我想改變這一行並應用位操作以最大化程序性能。我怎樣才能做到這一點?
謝謝。
如果基數是2的n次方,則可以用右移n來代替除法。然後,由於取一個整數的mod 256相當於取最後的8位,所以你可以用0xFF進行與之比較。或者,如果您使用256 * base進行AND操作,然後右移bit n,則可以撤消操作。
base_num = arr[j] >> n;
base_num &= 0xFF;
當然,任何half-decent編譯器都應該能夠爲你做到這一點。
您需要按'n'位進行移位,'2^n'爲'1 << n'。 –
[控制內核](http://www.kernel.org)的'pow'函數(來自[glibc](http://ftp.gnu.org/gnu/glibc/))定義在頂部作爲(簡化):'if(base == 2){return(1 << exp)}' –
你是對的,我會修復它:) –
將-O1
或更高版本添加到您的編譯器選項,編譯器將爲您完成。
在GCC,-O1
接通-ftree-slsr
其是,根據該文檔,
執行在樹上直線強度的降低。這識別涉及乘法的相關表達式,並在可能的情況下用較便宜的計算代替它們。
這將取代模數和基數,如果它是恆定的。但是,如果您知道基數將是某個非恆定的冪數,則可以重構周圍的代碼,以便爲該數字的log2
和>>
減去1。
你也可以只申報base_num
爲8位整數:
#include <stdint.h>
uint8_t base_num;
uint16_t crap;
crap = 0xFF00;
base_num = crap;
如果你的編譯器是標準的恭維,它會把的byte(0xFF00)
(0x00
)的值到base_num
。
我還沒有滿足,它以純C(既不C++或C#)飽和算術一個編譯器,但如果這樣做,它會把的sat_byte(0xFF00)
其比0xFF
數值越大,就會把0xFF
成base_num
。
請記住,在這種情況下,您的編譯器會警告您失去精度。在這種情況下,您的編譯器可能會出錯(Visual Studio與Treat Warnings as Errors
打開)。如果發生這種情況,你可以這樣做:
base_num = (uint8_t)crap;
但這似乎是你想要避免的。
你試圖做的似乎是去除模運算符,因爲這需要一個除法和除法是最昂貴的基本算術運算。我一般不會認爲這是任何方式與任何「智能」編譯器(甚至在調試模式)的瓶頸將「優化」它來:
base_num = crap & 0xFF;
支持的平臺上(每主流處理器我已經聽說 - x86,AMD64,ARM,MIPS),這應該是任何。聽說沒有基本的AND和OR算術指令的處理器,我會驚呆了。
「base」是一個常量,還是會改變? – Xymostech
如果編譯器是值得的,它會在每個平臺上用'&0xFF'替換'%256',這比'%'快。 'base'的價值是什麼? –
您可以將'base_num'聲明爲8位(無符號)整數 –