由這個想到的;
31乘以某個數能不能寫成這個數乘以2的次冪 再減去這個數。
用數學語言表達一下就是:
設這個數為x
31*x=x*2^n-x
這個等式是否存在,如果存在,求n的值
那我們計算一下,
31=2^n -1
得2^n=32
得n=5
也就是說存在那麼乙個n使得,31乘以某個數的結果等於這個數乘以2的n次冪再減去乙個數。
所以,乙個乘法運算,最後就轉化成了乙個速度較快的移位運算了。
我們再試試另外的數
63*i=i*2^n-i這個等式是寸存在,若存在,求出n的值。
最後得出n=6
有沒有發現規律,31等於2的n次方-1,63也等於2的n次方-1
所以乙個(2^n-1)乘以某個數的結果可以被優化為這個數乘以2的n次方再減去這個數。
然後我又做了幾個實驗。
因為9=2^4+1;
然後自然就想到了9乘以某個數是否能寫成這個數乘以2的n次冪,再加上這個數
9*i=i*2^n+i是否成立,如果成立,求n
n=4,也就是說9乘以某個數是等於這個數乘以2的n次冪再加上這個數的。
事實上,編譯器也是這麼優化的。
我寫了一段**,用來計算9和任意乙個整數的乘法。
int x =9;用ida檢視一下關鍵**,9是怎麼被優化的。int input = 0;
scanf_s("%d",&input);
printf("%d",9*input);
有一點必須直到,eax是作為printf的引數,printf的輸出結果就是eax的值,這需要一點彙編知識。
那我們看lea中eax是怎麼計算的。
用數學語言翻譯過來是不是就是這樣:
9*eax=eax*8 + eax;把eax換成i
9*i=i*2^n+i
和前面是相符的。
經過測試發現如果是單變數乘以某個常數這種情況的話,優化策略是這樣的:
如果這個常數可以被寫成2^n,(2^n)+1,(2^n)-1,2^n(1+2^m) 這幾種情況的話,那麼就被優化了。
2^n(2^m-1) 這種情況並不優化,直接用的是imul指令
編譯器優化
常量摺疊 a 1 2 由於結果可預見,編譯器直接生成a 3 常量傳播a 1 若後續 沒有更改a,則編譯器將a直接用其值1代替 減少變數 對於x和y的比較,可以轉換成if i j x i2 y j 2 if x y 複寫傳播 類似於常量長傳,不過傳播的是變數 若後續 未修改a的值,則編譯器用m代替a ...
編譯器優化問題
今天遇一程式,unsigned char a,b,c a 0x89 b a 1 c a b 在單步除錯的時候,觀察數值發現b的值為0,分析b的值應當為0x44,百思不得其解,通過檢視其彙編語句,發現問題所在。彙編語句如下 mov r7,tmod 0x89 mov a,r7 clr c rrc a a...
symbian gcc 編譯器 優化
1。公升級到gcce 4http www.cnblogs.com felixyeou archive 2009 02 18 1392847.html 2.gcce 優化引數,關於3rd mr和3rd fp1生成的安裝包大小http wiki.forum.nokia.com index.php e5 ...