2012-12-06 66 views
2

我在我的主機(linux x86)和目標機器(arm)上運行的C++中編寫了一個小應用程序。
我的問題是,在主機上我的二進制文件大小約爲700kb,但在目標機器上它大約爲7mb。
我在兩個平臺上都使用相同的編譯開關。我的第一次是,arget機器上的一個庫被靜態鏈接了,但我用objdump檢查了這兩個二進制文件,兩者都使用相同的動態鏈接庫。 所以任何人都可以給我提示,我怎麼能找出爲什麼有這麼大的差異?交叉編譯時的文件差異

+2

這是什麼應用程序?你究竟如何編譯和鏈接它?什麼版本的編譯器,鏈接器....給我們更多的細節.... –

+1

你檢查了靜態與動態鏈接? –

+2

剝離與未剝離的二進制文件有什麼關係?如果ARM二進制文件仍然有它的調試符號,它將會大得多。你可以嘗試剝離兩個二進制文件,看看會發生什麼...... – thkala

回答

2

雖然不同的計算機體系結構可以從理論上需要完全不同數量的可執行代碼用於同一個程序,但在現代體系結構中並不真正期望10的因子。 ARM和x86可能會有所不同,但它們仍然設計在同一個宇宙內存和帶寬不可浪費的地方,這導致CPU設計人員盡力保持可執行代碼儘可能的緊湊。

我,所以,看看下面的可能性,以概率:

  • 符號剝離:如果兩個二進制文件之一已經從它的符號剝離,那麼這將是顯著更小,尤其是如果使用調試信息進行編譯你可能想試圖去掉兩個二進制文件,看看會發生什麼。

  • 靜態鏈接:我偶爾會遇到用於嵌入式目標的構建系統,它們寧願使用靜態鏈接來使用共享庫。檢查每個二進制文件的庫依賴關係可能會檢測到這一點。

  • 其他啓用的代碼:較大的二進制文件可能會啓用其他代碼,例如,構建系統找到了一個附加的可選庫,或者因爲目標平臺需要特定的處理。

    儘管如此,10的因子可能太多了,除非較小的二進制文件缺少很多功能,或者較大的一個靜態地鏈接到某些可選庫中。

  • 不同的編譯器配置:你不應該只看編譯器選項你提供的,而且編譯器使用的默認值是每個目標。例如,如果編譯器在一個體繫結構中具有顯着更高的內聯或展開循環展開限制,則可執行結果可能會明顯變差。

+0

我應該想到自己剝離。我沒有弄清楚我的構建有什麼區別,但是目前我的可執行文件的後期剝離就足夠了。感謝提示。 – mkaes

1

首先沒有理由期望爲不同體系結構編譯的相同代碼在大小上有任何種類的關係。你可以很容易地讓A比B大,然後改變一行代碼,然後B比A大。

其次,你所說的「二進制文件」是我猜小精靈,這是一個二進制和一些開銷很大。架構和其他此類事物之間的開銷可能有所不同。

如果您針對兩種體系結構/平臺編譯相同的代碼,或者針對相同體系結構使用不同的編譯器或編譯選項,則沒有理由期望文件大小彼此具有任何關係。

+1

同意,但我希望在x86和ARM之間至多有2倍。 10的因素似乎對不同的彙編/臨時選項有所懷疑 –

0

不同的體系結構可以有完全不同的方式來處理同樣的事情。例如,在CISC(例如x86)架構上加載立即值通常是一條指令,而在RISC(例如ppc,arm)上它通常是多於一條指令,所需的實際數目取決於該值。例如,如果指令集只允許16位立即值,則最多可能需要7條指令來加載64位值(加載16位並在兩個加載之間切換)。因此,代碼本質上是不同的。

0

到目前爲止尚未提及但與ARM/x86比較相關的一個原因是浮點仿真。目前所有的x86芯片都具有本地FP支持(即使通過SSE支持SIMD FP也支持x86-64),但ARM CPU通常缺少FP單元。這反過來意味着即使是簡單的FP加法也必須轉化爲指數和尾數的整數運算的長序列。