鬱悶的彙編碼

來源:互聯網
上載者:User

    我是個編程業餘愛好者,雖說是業餘,也有近20年了,以前在DOS下編程,電腦速度很慢,記憶體、硬碟容量也有限,必須對程式碼精益求精,稍大點的程式還得兼顧代碼長度和運行速度,否則,你的程式可能跑不起來。
    我以前主要用C編程,雖然效率較高,但為了代碼長度和速度,關鍵的代碼我喜歡用彙編,相同的演算法和流程,ASM和C無論是代碼長度和運行速度,都沒得比,而且有些特殊的位元運算,ASM比C方便多了。在當時dBASE流行的時代(除去系統程式和科技應用及少量的專用商業程式,其它應用幾乎清一色dBASE),我的程式還是很受歡迎的(免費的當然受歡迎啦),為此還獲得過本系統省級和部級優秀程式獎。新的世紀到來,無論是C還是ASM,幾乎有出局的危險,我又喜歡上了DELPHI(DELPHI也快出局了),十年了,C都忘了,而ASM因時不時我喜歡來個BASM函數,所以還沒全忘。
    前幾天,有人在CSDN的組合語言板塊發了個《千分求最快的Base64編碼函數》的帖,而剛好我有個Delphi的BASM函數放在BLOG中(參見《Delphi版的Base64轉換函式(修改版)》,其中的代碼已經是修改過的),自己測試了一下,在我的機器上87MB/s,於是拋磚引玉推薦給了樓主,樓主測試有266MB/s(我的機器是P464位 2.8G,DDR2 667 1G雙通道,樓主的是AMD64x2 3600+(2.01G), DDR2 667(334.9MHz))。後來,向樓主推薦代碼的越來越多,速度也是越來越快,由幾十/s上升到IGM/s以上(樓主測試的),而且有個有趣的現象,相同的演算法和流程,C/C++代碼普遍比ASM快,在我的印象中,這應該是不可能的,只要彙編碼最佳化到位,速度絕對高於C/C++,於是對我的Base64Encode函數在不改變基本演算法的基礎上進行了一些簡單最佳化,自己測試164/s,速度比以前提高近一倍,但還是很不理想,沒想到樓主的測試結果更氣人,居然比我那個沒最佳化的函數還慢,不同的CPU竟然有如此大的懸殊,鬱悶!反覆最佳化後的代碼速度也不理想,自己測試470MB/s(沒改變嵌套迴圈流程,如果改用順序執行流程,速度可大大提高,但是我很不喜歡這樣的“油條代碼”)。

    不是C/C++比ASM快嗎,於是用C寫了2個函數試試,主要代碼如下:

static const char base64table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";


unsigned long Base64_Encode_Byte(void *Source, unsigned long SourceSize, void *Base64_out)
...{
 unsigned char *pIn = (unsigned char*)Source;
 unsigned long *pOut = (unsigned long*)Base64_out;
 unsigned long *pOut_end = pOut + SourceSize / 3;
 for (; pOut < pOut_end; pOut ++, pIn += 3)
 ...{
  *pOut = *(base64table + (pIn[0] >> 2))
     | *(base64table + (((pIn[0] << 4) | (pIn[1] >> 4)) & 0x3f)) << 8
     | *(base64table + (((pIn[1] << 2) | (pIn[2] >> 6)) & 0x3f)) << 16
     | *(base64table+ (pIn[2] & 0x3f)) << 24;
 }
 Base64_addpaing(pIn, SourceSize % 3, pOut);
 return ((SourceSize + 2) / 3) << 2;
}

unsigned long Base64_Encode_Bit(void *Source, unsigned long SourceSize, void *Base64_out)
...{
 unsigned char *pIn = (unsigned char*)Source;
 unsigned long *pOut = (unsigned long*)Base64_out;
 unsigned long *pOut_end = pOut + SourceSize / 3;
 unsigned long data;
 for (; pOut < pOut_end; pOut ++, pIn += 3)
 ...{
  data = *pIn << 16 | pIn[1] << 8 | pIn[2];
  *pOut = *(base64table + (data >> 18))
     | *(base64table + ((data >> 12) & 0x3f)) << 8
     | *(base64table + ((data >> 6) & 0x3f)) << 16
     | *(base64table + ((data) & 0x3f)) << 24;
 }
 Base64_addpaing(pIn, SourceSize % 3, pOut);
 return ((SourceSize + 2) / 3) << 2;
}

    Base64_Encode_Byte是按位元組拆分後移位重新組合的傳統演算法,而Base64_Encode_Bit則是先組合成24位二進位記憶體映像再拆分。在BCB上編譯運行,沒選擇最佳化的Debug程式都沒超過300MB/s,且Base64_Encode_Byte比Base64_Encode_Bit要快一些,開啟最佳化的Release程式都可達550MB/s以上,而此時Base64_Encode_Bit反倒比Base64_Encode_Byte差不多快30MB/s。C代碼果真比普通ASM快!我用BCC32 -S -O2 -6編譯命令取得Base64_Encode_Bit最佳化後的ASM代碼,幾乎沒作修改改名為Base64_Encode_ASM編譯為Release程式測試,暈!只有470MB/s多。難道BCB給的不是最佳化ASM碼?不得而知,鬱悶!
    再次反省總結,決定仿效C的ASM碼,採用順序流程(雖然不喜歡,但還是試試)和傳統演算法重新寫了個BASM函數,居然達到710MB/s!相同演算法,順序流程比迴圈流程快是肯定的,但編程老手們是不願意為了一點點速度而放棄合理的流程的,確實影響代碼的美觀和可讀性。可是現在也太離譜了,我只要一改為迴圈,速度就成倍下降,真是鬱悶!
    好了,總算有可同《千分求最快的Base64編碼函數》貼上高手們相媲美的BASM函數了(貼上雖然有1GMB/s左右的函數,但那是拼記憶體消耗拼出來的,常規演算法我這應該算高的了,而且我的機器比他們的慢,估計樓主的測試怎麼也有個800-900MB/s吧!),為了放心起見,我沒發到貼上,而是發CSDN簡訊給樓主,讓他測試一下,畢竟是他發的貼,以他的測試為準,不一會,結果出來了:“新的Base64_Encode在我的AMDx2 4200+上 427.9MB/s”,注意,是比前面的AMD64x2 3600+(2.01G), DDR2 667(334.9MHz)更快的機器上測試結果!真是鬱悶到極點了!!!
    彙編碼比進階語言相容性和移植性差,是個不爭的事實,但不同的CPU竟然如此大的懸殊,不能不令人悲哀,看來我崇尚的進階語言與ASM組合編程方式應該結束了。
    推而廣之,進階語言原生代碼程式也不可能為每種CPU都編譯一個版本,這台機器上跑得很歡的程式到另一台機器上會不會其慢無比?看來說原生代碼程式幾年後將被JAVA、.NET等中介軟體Managed 程式碼程式取代應該是不假了,難怪有人宣稱JAVA的運行速度將超過C/C++,看來也不是不可能,因為中介軟體Managed 程式碼完全可根據不同的機器特性提供最高效率的代碼!
    以上只是筆者有感而發,有些觀點不見得正確,畢竟我只是個業餘愛好者,而且年紀很大(多大?你可能猜不著),文化水平也很低(多低,你可能也想不到),同高手們是有相當大的差距的,還希望不吝賜教!

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.