麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Delphi > 正文

Delphi與匯編雜談(2)

2019-11-18 18:30:02
字體:
來源:轉載
供稿:網友
 

                                                                                                                初級優化篇

說到優化,很多人又不屑一顧了,“現在計算機速度都那么快了,再快那么百分之幾有什么意義啊”。這么說確實有些道理,現在的編譯器編譯后的結果已經是充分優化過了,除了圖形圖像多媒體等特定軟件的開發外、多數情況下刻意的優化確實沒必要,但是如果開發人員在編寫代碼的時候已經具有了優化意識,在完成優化的同時,又能保證了甚至提升開發效率,何樂而不為呢?

當然,算法的設計都是優化的核心,絕大多數情況下,程序的執行效率高低主要由開發人員對程序整體把握,算法的設計等來決定!但有時候針對細節的優化也是有一定意義的!

而且這種優化在很多情況下也并不需要直接通過匯編來寫代碼實現,但這種情況下卻也能體現出掌握匯編知識的優越性!

如下面兩個函數:

function GetBit(i: Cardinal; n: Cardinal): Boolean;
begin
  Result := Boolean((i shr n) and 1);
end;

function GetBit(i: Cardinal; n: Cardinal): Boolean;
begin
  Result := Boolean((1 shl n) and i);
end;

對應的匯編代碼:

MOV ECX, EDX
SHR EAX, CL
AND EAX, $01

MOV ECX, EDX
MOV EDX, $01
SHL EDX, CL
AND EAX, EDX

它們的作用一樣,都是取i某位的值,為1返回True,0返回False!

表面上看可能都會認為兩個函數的執行效率一樣,實際上還是有區別的,第一段程序是的移位操作是對i進行的,按照Delphi中默認的調用約定register,此時的i的值是存在寄存器EAX中,移位操作可直接完成;而第二段程序則不同,要對立即數1完成移位操作,必須先將其傳送到寄存器,由此也就必然多出一條指令!當然也不是所有情況下,指令少就一定比指令多要快,具體執行時還要考慮指令執行的時鐘周期和指令的配對等問題(后面再介紹些),獨立出來也說明不了問題,只有在具體代碼環境中才好作比較。

一般情況下這種效率上的執行差異實在是太微不足道了,但在編程期間時刻保持著優化的意識絕不是件壞事!如果此類代碼位于循環的最里層,N個時鐘周期經過大量循環的累積,產生的執行效率差異也可能變的很大!

上面只是個很小的例子,由此可以看出在開發中如果能站在匯編的角度思考一些問題,能在保證開發效率的同時用高級語言編寫出更有效率的細節代碼!但還有很多時候,細節優化還要用使用嵌入匯編代碼來完成,而且有些時候由于嵌入匯編代碼應用,還能使代碼編寫變得更有效率。

如需要將一個32位數的字節順序顛倒,在Delphi中,完全用高級語言實現怎么做?用移位可以,多次調用內建函數Swap也可以,但是如果想到一條BSWAP指令,這一切變得很簡單。

function SwapLong(Value: Cardinal): Cardinal;
asm
  BSWAP EAX
end;

注:同上,Value的值是存在寄存器EAX中,而32位數的值也通過EAX返回,所以只需要一句即可。

當然多數的嵌入匯編優化沒有這么簡單,不過通過大學里所學的那一點點匯編知識也很難做到更深入的優化,也只能通過不斷的積累,對比編譯后的匯編代碼獲取經驗!好在多數情況下,細節優化并不是程序設計的主體。

但如果所開發程序涉及到圖形圖像多媒體等方面,還是有必要進行更深入的優化的!好在不管是浮點指令的優化還是應用MMX、SSE、3DNow等完成優化,Delphi6都能提供良好的支持。即使是想早期版本的Delphi支持這些CPU擴展指令集或者想要支持以后新的CPU指令集,利用Delphi在嵌入匯編中所支持的DB、DW、DD、DQ等四條匯編指令(在Borland的Delphi6官方語言手冊里只說支持DB、DW、DD)插入相關指令的數值表示也能靈活的實現。

如:

DW $A20F //CPUID

DW $770F //EMMS
DB $0F, $6F, $C1 //MOVQ MM0, MM1

了解指令只是基礎,在圍繞FPU,MMX,SSE設計完算法后,想更深一步的進行優化,還必須了解一些CPU本身的技術特性。

先看看下面兩段代碼:

asm
  ADD [a], ECX
  ADD [b], EDX
end

asm
  MOV EAX, [a]
  MOV EBX, [b]
  ADD EAX, ECX
  ADD EBX, EDX
  MOV [a], EAX
  MOV [b], EBX
end

第二個效率高?錯了,如上面說的,指令少不意味著執行效率高,查查相關資料可知,第一段代碼的兩條指令執行的時鐘周期為3(每條指令都需要完成讀、改、寫三步),第二段代碼中的6條指令執行的時鐘周期都為1。那么說兩段代碼效率一樣?又錯了,實際上第二段代碼執行效率比第一段代碼要高!為什么?因為奔騰級以后的CPU都有兩條流水線來執行指令,所以當相鄰的兩條指令能夠完成配對,那么它們就能夠同時執行!具體到上面的兩段代碼來說具體原因又是什么呢?

第一段代碼中的兩條指令雖然可以完成配對,但需要的總執行時鐘周期為5而不是3,而第二段代碼的六條指令可以兩兩之間并行執行,所以也就導致了這個結果。

說到這里,都是些很淺顯的例子,本身給不了大家太多的幫助。如果真的想優化特定程序,還是找些FPU,MMX優化的專題文章看看,或者找來技術手冊好好專研專研“亂序執行”和“分枝預測”等技術。只希望各位在上大學的朋友們不要只專注于那些“能賺錢”的開發工具和時髦的新技術,能把更多的時間花在打基礎上,有了扎實的基礎才能快速掌握新知識、才能用更快的時間掌握新的開發工具、才能...(省略一千字)。

不過話又說回來,知識還是要用來解決實際問題的,如果每天就只在技術細節上做文章,也許能成為一個出色的黑客,但絕對開發不出一流的軟件。所以還是要以創造價值為根本目的。所以...不說了,再說下去就真不像技術文章了。^_^

附:程序優化除了考慮執行效率以外,當然也要考慮體積的問題(體積小才能更快的載入內存,更快的完成指令譯碼等工作),比如清空EAX寄存器都是用SUB EAX, EAX或XOR EAX, EAX而不會用MOV EAX, $0,雖然它們的執行時鐘周期都是1,但前者的指令長度(2字節)明顯比后者(5字節)短。但因為上面說的都是些細節,所以沒提到體積的問題。更多的縮小體積的問題還是交給編譯器去解決吧,在編寫嵌入ASM代碼的同時稍微注意一下就可以了。


上一篇:用DELPHI開發自動化服器

下一篇:用DELPHI開發DirectX游戲

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

主站蜘蛛池模板: 久久久久久久久久久av | 亚洲一区二区免费 | 国产二区三区在线播放 | 一级毛片看 | 国产精品区一区二区三区 | 免费专区 - 91爱爱 | 大学生一级毛片在线视频 | 日本成年免费网站 | 免费a级毛片大学生免费观看 | 亚洲欧美不卡视频 | 久久精品亚洲精品国产欧美kt∨ | 久久综合伊人 | 欧美日韩在线播放 | 国内免费视频成人精品 | a级高清免费毛片av在线 | 日韩精品一区二区三区中文 | 91网页视频入口在线观看 | 在线成人av观看 | 午夜久久久精品一区二区三区 | 斗罗破苍穹在线观看免费完整观看 | 毛片视频网站在线观看 | 一区二区美女视频 | 日韩在线欧美在线 | 51色视频 | 欧美激情精品久久久久久久久久 | av在线免费网 | 国产精品久久久久久久四虎电影 | 男女羞羞在线观看 | av手机在线电影 | 粉嫩av一区二区三区四区在线观看 | 黑人一级片视频 | 中文字幕网址 | 国产精品久久久久久久久久久久午夜 | 久久成年网站 | 欧美一级一区二区三区 | 国产一区二区免费 | 欧美综合成人 | japanese xxxxhd | 国产精品一区二区视频 | 看91| 精品久久久久久久久中文字幕 |