OS 7: 如何為iPhone 5S編譯64位應用。
隨著iPhone 5S的推出,大家開始關心5S上所使用的64位CPU A7。
除了關心A7的效能以外,大家還會關心一個問題,那就是使用A7的64位系統對應用有沒有什麼要求。特別是應用開發者,大家都比較關心我們的應用如何遷移到64位的系統上來,以充分發揮A7的能力。其實這些問題都可以在蘋果的官方文件《64-Bit transition Guide for Cocoa Touch》中找到答案。
為了大家方便,我將《64-Bit transition Guide for Cocoa Touch》中的一些重點整理了一下,希望可以為大家節約一些詳細閱讀文件的時間,如果我理解有不對的地方請大家指正。
首先,A7使用的是ARM V8架構,除了使用64位的地址匯流排和64位的暫存器以外,還增加了暫存器的數量,目前A7中的整數和浮點數暫存器是A6的兩倍。
這裡需要強調的是,暫存器的增加大大提高了程式的執行速度。將CPU由32位提高到64位,最主要的改變增大了定址能力,可以突破32位系統只能訪問3G記憶體的限制(感謝 wanglang3081 指出這裡的問題,32位系統在理論上可以訪問4G記憶體,因為2的32次方約等於4
290 000 000,很多32位系統只能訪問3G左右的記憶體是因為有一大部分地址被分配給I/O系統了,所以總體可用記憶體就不足4G了。),但是,32位到64位的改變並不一定意味著程式執行速度的提高,甚至有些情況下會因為64位系統中的資料佔用記憶體變大而導致程式執行速度變慢。而暫存器數量的增加,則直接提高了程式執行速度,當然,前提是你的應用需要重新為64位系統編譯一遍,讓程式可以充分使用所有的暫存器。
使用Xcode 5可以很方便地將以前的應用編譯成64位程式,基本過程如下:
1. 使用Xcode 5 開啟原有專案。
2. 將支援的裝置改成“iOS 7”。
3. 在“Build Setting”中將“Architectures”改成“Standard Architectures (including 64-bit)”。
4. 執行測試程式,解決編譯過程出現的問題。
其中第4步是關鍵,具體會遇到什麼問題和原來程式的設計有關,包括使用資料型別的方式是否標準等,後面會繼續討論細節,其實《64-Bit transition Guide for Cocoa Touch》一書主要就是講這些細節。
在討論細節之前有一些較為巨集觀的內容大家可以瞭解一下。
Xcode 5編譯的iOS 7程式包含了32位和64位兩套二進位制程式碼,在32位的iOS系統上會呼叫32位的二進位制程式碼,在64位系統上會呼叫64位的二進位制程式碼,以此來解決向後相容的問題。
同時,考慮到很多32位的程式可能在沒有重新編譯的情況下部署到64位系統上,64位的iOS系統中帶有兩套FrameWork,一套是32位的,一套是64位的。
當64位的iOS系統執行原來的32位程式時,系統會呼叫32位的FrameWork作為底層支撐,當系統執行64位程式時,系統會呼叫64位的FrameWork作為底層支撐。
也就是說,當一個iPhone 5S上同時執行32位程式和64位程式時,系統同時將32位和64位兩套FrameWork載入了記憶體中,所以消耗的記憶體也比較多。
如果一臺64位的iOS裝置上執行的所有程式都是為64位系統編譯過的,iOS系統將只載入64位的FrameWork,這將節省好多記憶體。所以,如果大家都可以快速將程式傳換成64位的,iOS將跑得更快。真的是“大家好才是真的好”。
後面我們來看看一些為64位系統調整程式的技術細節。
32位的iOS系統和64位的iOS系統主要的差別有兩個,一個是資料型別的差別,一個是過程呼叫方法的差別。
在資料型別上,主要的變化是指標型別(Pointer)和長整數型別(long)的長度變化和記憶體對齊方式的變化,同時也導致了更高階別資料型別的變化,如NSInteger的長度也有變化。
在過程呼叫方法上,因為ARM
V8 和ARM V7具有不同數量的暫存器,具有不同的過程呼叫約定,所以32位系統和64位系統在彙編層級是不同的。
根據以上兩方面的變化,書中總結了以下要點,開發人員根據以下要點來檢查原來的32位程式碼就差不多可以將應用移植到64位系統上了:
1. 不要將長整型資料(long)賦予整型(int)
這種程式碼在32位系統上沒有問題,因為在32位系統中long和int的長度是一樣的,不過在64位系統中就有可能出問題,因為64位系統中long比int長,將long值賦予int將導致資料丟失。
2. 不要將指標型別(Pointer)賦予整型(int)
為了方便地址計算,有時程式設計師會將指標型別賦予整型,這種程式碼在32位系統上沒有問題,因為在32位系統中Pointer和int的長度是一樣的,不過在64位系統中就會有問題,因為64位系統中Pointer比int長,將Pointer值賦予int將導致地址資料丟失,最終導致嚴重問題。
3. 留意那些和數位相關的數值計算
比如掩碼技術,如果使用一個long型別的掩碼,轉到64位系統後高位都是0,計算出來的結果可能不符合預期。還有無符號整數和有符號整數的混用等。
4. 留意對齊方式帶來的變化
如果在32位系統上定義一個結構包含兩個long型別,第二個long數值的偏移地址是4,可以通過結構地址+4的方式獲取,但是在64位系統上就不行了,因為在64位系統中第二個long數值的偏移地址是8。
5. 充分考慮在32位應用和64位應用之間的資料交換
因為使用者會通過網路交換資料,同時使用者儲存的資料也可能通過備份等方式在32位系統和64位系統之間切換,所以應用在儲存和傳送流資料的時候一定要考慮充分。比如資料在32位系統中儲存,在64位系統中能否正常開啟,或者反過來,在64位系統中儲存,在32位系統中開啟是否正常。
6. 重寫所有彙編程式碼
這點無需說明,如果你在程式碼中嵌入了彙編程式碼,你需要參考64位系統的指令集重寫彙編程式碼。
7. 不要將可變引數的過程強制轉換為定參過程,也不要將定參過程強制轉換為可變引數的過程。
這時因為32位系統和64位系統對於這兩種過程呼叫方式的處理方法不同。
按以上幾個重點去檢查程式就差不多了,當然,具體的細節還有很多,需要在實際工作中結合程式碼和除錯結果進行分析。
總之,建議具體負責應用遷移的開發者需要完整閱讀《64-Bit transition Guide for Cocoa Touch》。
相關文章
- [譯] 如何編寫全棧 JavaScript 應用全棧JavaScript
- .NET應用如何防止被反編譯編譯
- 【go】【應用編譯】Go編譯
- 編譯 asp 應用程式成為 exe 檔案 (轉)編譯
- OS X編譯安裝Mariadb編譯
- webpack 應用編譯優化之路Web編譯優化
- OS-鴻蒙系統-以及編譯器鴻蒙編譯
- PHP7.0.0在OS X編譯安裝PHP編譯
- watch OS 3釋出:應用啟動速度飆升7倍
- Numba編譯器的介紹與應用編譯
- iOS編譯過程的原理和應用iOS編譯
- 編寫 iPhone Friendly 的 Web 應用程式 (Part 6 - iUI)iPhoneWebUI
- 如何在CentOS7安裝Node?(編譯安裝)CentOS編譯
- [譯] 如何在瀏覽器中編寫一款藍芽應用瀏覽器藍芽
- [Python]OS模組應用Python
- 為 OS X 開發者準備的 15 個超棒應用
- 為OS X開發者準備的15個超棒應用
- 如何在Chrome OS上安裝Linux應用程式ChromeLinux
- [譯] 為什麼我用 JavaScript 來編寫 CSSJavaScriptCSS
- [bazel]-如何編譯編譯
- iOS 7: iPhone/iPad應用開發技術詳解iOSiPhoneiPad
- 編譯和分發 Chez Scheme 應用程式編譯Scheme
- <摘錄>如何在64位linux強制編譯32位應用程式Linux編譯
- 用jb7編譯jdon的錯誤,請高手看看編譯
- PHP7 編譯安裝PHP編譯
- 在CentOS 7上編譯QtumCentOS編譯QT
- 編譯安裝php7編譯PHP
- php7編譯安裝PHP編譯
- Go - armv7 交叉編譯Go編譯
- Nginx 簡單應用(Windows os)NginxWindows
- 編譯器如何生成彙編編譯
- iOS 8 Beta 3為iPhone 5S帶來健康資料追蹤功能iOSiPhone
- 全圖化引擎(AI·OS)中的編譯技術AI編譯
- 如何在iphone應用程式中傳送簡訊iPhone
- iphone 5s cases best buy among the livingiPhone
- Linphone-iPhone下載和編譯sdkiPhone編譯
- iPhone7/Plus續航如何 iPhone7/7 Plus續航表現資料iPhone
- 如何用cmake編譯編譯