經典:反轉一個字節


這道題很古老了,可別將它和大端轉小端混淆了,所謂大端和小端指的是字節序,而這里反轉一個字節說的是位序,算法更是不勝枚舉,說實話都能達到目的,剩余的就是看看誰的效率更高了,基本上這是一個最難的問題,高手不是能寫出最美麗的程序而是能寫出既美麗同時效率又是最高的程序,如果一個人寫的程序很美麗,很直觀,只能說明該程序員對語言掌握的很好,但是語言畢竟只是工具,真正做事的是計算機,只有對計算機很了解,才能寫出效率最高的程序,正如文學家的文筆很多不如花季少女,但是花季少女永遠也超越不了時代。

不管什么樣的程序,落實到底層的cpu都是那幾樣,盡量不要使用跳轉,因為會清空流水線,相比之下,跳轉的危害在x86機器上intel比AMD更甚,因為后者的流水線更淺;充分利用超標量cpu的超標量特性,也就是盡量使相鄰指令不要關聯,這樣可以亂序執行,亂序執行就是將指令發射到不同的流水線序列;徹底理解cpu的HT特性,HT不一定會更好,因為它們畢竟是要共享一套算術單元,有時切換的開銷會抵消對空閑周期的彌補,總的看來,cpu類型的程序應該避免使用HT,映射到進程/線程模型,並不是線程越多越好,當線程太少,不能利用多cpu特性,並且可能會使cpu閑置,但是太多的話又會引入切換/保存上下文開銷,因此線程的數量和cpu數量相等或者比cpu數量大1個或者2個最好,因為強制和cpu數量相等會加大操作系統的運行開銷,並且萬一線程陷入IO沒有替補,因此Windows的IO完成端口就設計的特別好,windows內核會限制完成端口上的活躍線程和創建時傳入的參數一致,但是我並不贊成這種策略在內核實現,因此機制和策略嚴格分離的unix就沒有這么做,你完全可以在用戶空間通過cpu綁定和線程數量限制來調優;要盡可能的利用cpu的L1/L2 cache,理想情況就是,靜態數據在cache中,該線程永不換出,cache永不刷新,但是這僅僅是一種理想,因此就要在理想和現實之間折中,將靜態數據減少,既然不能將cache歸為己有,那么也沒有必要為止付出太多空間開銷。

在上一段的指導下,高效的算法應該是很少的跳轉,也就是很少的判斷,不多不少的靜態數據,該算法是cpu類型的,HT應關閉,如此的條件用匯編最好了,但是還要和另一個條件折中,這就是程序的美觀性,於是還是用c吧:

unsigned char func( unsigned char c){

    static unsigned char sta[16] ={//不多不少的靜態數據
        0x00,0x08,0x04,0x0C,0x02,0x0A,0x06,0x0E,0x01,0x09,0x05,0x0D,0x03,0x0B,0x07,0x0F
    };

    unsigned char d = 0; //沒有判斷
    d |= (sta[c&0xF]) << 4;
    d |= sta[c>>4];
    return d;
}

小聲說一句,此題的解法甚多,比如可以定義一個大表,比如可以用二分法,或者按照管道的思想,一端進一端出,其實就是堆棧,將一個數按照一位一位的進入一個堆棧,然后再彈出,如果不是按位倒序,linux內核中有足夠的算法供你參考,如果你在筆試時寫上了linux內核的算法,那么考官最起碼會覺得你說的讀過內核並不假,但是可悲的是考官他自己不一定讀過內核。要知道很多30歲以上的軟件工程師都不一定能寫出什么高效的算法,我們公司就有一批這樣的可悲人群,乃不知有寄存器,無論堆棧!

轉自:http://blog.csdn.net/dog250/article/details/5302952

推薦:http://blog.vckbase.com/panic/archive/2005/06/11/6389.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM