2011-02-18 70 views
2

我已經編寫了在嵌入式處理器(ARM)上運行的算法的兩種不同的C實現。我想一個公平的方式,以這兩種實現在 代碼大小方面比較,因此下載的可執行文件時,我得到了以下數字:代碼大小的公平比較

Implementation One 

.text size 55098 bytes 
.data size 2048 bytes 

Implementation Two 

.text size 54598 bytes 
.data size 2048 bytes 

在.text段差爲500個字節,但在相對條件不是很多。問題是,該圖還包含引導代碼,這些引導代碼包含在可執行文件中,以便可以在獨立模式下調用,即在嵌入式處理器上沒有操作系統的情況下。

我想知道如果有人有一個想法如何得到可執行代碼的實際代碼大小沒有所有臃腫的額外代碼。

非常感謝 安德魯

+0

配售bootloader的它自己的專用內存段應該解決這個問題,是嗎?任何你不這樣做的理由? – Lundin 2011-02-18 10:04:15

回答

0

你應該定義什麼是extra code的一部分。希望你已經在另一個編譯單元中編寫了這個額外的代碼。你的工具鏈應該有工具來檢測編譯單元的代碼大小。

最重要的是,您應該將代碼大小與availbale內存進行比較。如果您沒有要求將代碼放入指定的內存區域,那麼減少代碼大小並不值得。

8
  1. 您的C編譯器通常可以生成您可以檢查的彙編源代碼。
  2. 另一種可能性是從鏈接器中查看映射文件,它應該爲您提供單個函數的大小。
  3. 您可以使用調試器查看二進制代碼。

要獲取asm輸出或映射文件,您需要爲編譯器和/或鏈接器指定適當的選項。這些選項取決於您使用的工具鏈(編譯器,鏈接器)。

從GCC獲得ASM輸出: 的gcc -o -S hello.c的hello_asm.s

2

你的鏈接器可以幾乎肯定生成一個映射文件(可能已經這樣做),將顯示(以分鐘詳細)所有單個數據和代碼對象的內存使用情況詳細信息,當然也包括對象模塊級別,通常是單個函數和數據對象級別。

1

最終所有的代碼將被下載,引導程序和操作系統包括在內。那麼,爲什麼你想排除他們的措施呢?

一個簡單的方法來知道你想排除它與應用程序編譯儘可能簡單的代碼的大小(例如main(){})。那麼你只需要減去你的下一個度量所獲得的值。

+2

同意 - 雖然「你爲什麼要排除他們的措施」不一定是一個反問題的問題;有幾種可能的原因可能會導致你這樣做(或者你爲什麼錯誤地認爲你會這麼做!);你的問題的正確答案很可能取決於它是什麼原因。 – 2011-02-19 21:19:01

0

一種可能的方法是讓您的構建工具以更精細的粒度轉儲出地圖。

例如,如果您使用的是gnu工具集,則可以在.elf文件上使用運行size,並根據其中的對象文件對其進行細分。

您還可以使用.elf文件中的objdump來獲取相當詳細的地圖。

假設您的示例中的引導代碼在兩個整體實現之間保持不變,使用這些工具應該讓您更好地瞭解哪一個具有更好的代碼空間效率。

0

如果您使用的是GNU工具,則可以使用size工具。它會告訴你任何目標文件在每個部分中使用的內存量。在你的情況下,你需要確保你要測量的代碼在它自己的文件中。

下面是輸出的一個例子:

text data  bss  dec  hex filename 
9767  4 5184 14955 3a6b cfi_flash.o 
1138  0  192 1330  532 cfi_mtd.o 
556  0  128  684  2ac mtdcore.o 
3897  0  8 3905  f41 mtdpart.o 
0

它有時是很難計算實現的尺寸孤立,因爲一些實現需要庫函數被鏈接在別人所沒有的。如果例程#1比#2小300字節,但需要500字節的庫例程foo(),並且例程#3比#4小300字節,但也需要相同的例程,然後有效隔離#1大於#2的200(即500-300)字節,而隔離的#3將比#4大200字節,但#1加#3將比#2加#4小100字節(因爲庫例程會只需要一次)。

如果某些庫函數產生了某些庫函數的降低功能(和降低成本)的替代方案,則經常會出現這種情況。如果可以避免使用昂貴的庫例程,那麼編寫和使用更簡單的版本可能是值得的。另一方面,如果代碼最終使用昂貴的例程,那麼更簡單的版本可能會變得多餘。

0

你可以寫一個「Implementation Null」,它只有一個存根功能,它不會做任何事情。這會給你一個基準值,用於比較。

(試行一個尺寸 - 實現零的大小) 與 (試行兩種尺寸 - 實現零的大小)