交叉GCC與浮點處理

來源:互聯網
上載者:User

很多講ARM Linux核心編譯的文章或手冊都會說
由於arm沒有浮點副處理器,所以需要一個類比浮點機制,
在配置核心時一定要選擇一個浮點模擬器NWFPE,如下
--- At least one math emulation must be selected │ │
│ │ <*> NWFPE math emulation │ │
│ │ [ ] Support extended precision │ │
│ │ < > FastFPE math emulation (EXPERIMENTAL)
如果沒有浮點模擬器,就會出現錯誤。比如未定義的指令:
init (1): undefined instruction: pc=4004b020
Code: e3a01000 00000000 00000000 00000000 (eca0420c)
實際上,即使使用了NWFPE,系統的浮點問題也並沒有完全解決

NWFPE類比浮點是利用了undefined instrction handler
即每次浮點指令操作,都會發生一次未定義指令異常(exception),
在這個異常的handler裡面,用軟體的方法模擬一個浮點指令
如果軟體裡的浮點運算比較多,那豈不是不停的請求CPU執行undefined instruction,然後產生異常?
答對了,核心類比浮點指令事實上就是這麼回事
這麼做帶來的後果是帶來極頻繁的exception,大大增加中斷延遲
換句話說,降低系統即時性
另外,每發生一次浮點操作,都要陷入到exception,不難想見會帶來極大的效能開銷。
核心類比浮點指令,要實現一個大的case switch
通常情況這個分支預測都會不命中,既要多浪費cpu clock
還會排空BTB,進一步降低後面分支預測命中率

怎麼辦?——使用軟浮點!

軟浮點支援是由交叉工具鏈提供的功能,與Linux核心無關
當使用軟浮點工具鏈編譯浮點操作時,編譯器會用內聯的浮點庫替換掉浮點操作
使得產生的機器碼完全不含浮點指令,但是又能夠完成正確的浮點操作
由於是在編譯時間最佳化,這種方式能夠讓CPU即使作浮點運算時也能夠執行連續的指令,減少程式分支
使用軟浮點工具鏈編譯產生的浮點操作速度較快
比NWFPE類比快一個數量級
我們怎麼知道交叉工具鏈是否支援軟浮點呢?
很簡單,使用編譯命令時加上-msoft-float這個CFLAGS就可以了,比如
arm-linux-gcc test.c -msoft-float -o test
如果工具鏈支援軟浮點,那麼就可以產生可執行檔
如出錯,對不起,該工具鏈不支援
另一個評鑑的方法,拿到一個編譯產生的檔案,使用
arm-linux-readelf -e test
可以列印出elf檔案頭資訊
在裡面看到software FP就是軟浮點格式,否則不是
Flags: 0x202, has entry point, GNU EABI, software FP

 

ZIX開發環境附帶的工具鏈完善支援軟浮點
下面是一個完整的支援軟浮點的頭部例子
使用arm-linux-readelf -e test輸出

ELF Header:
Magic: 7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: ARM
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x839c
Start of program headers: 52 (bytes into file)
Start of section headers: 3432 (bytes into file)
Flags: 0x202, has entry point, GNU EABI, software FP
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 6
Size of section headers: 40 (bytes)
Number of section headers: 31
Section header string table index: 28

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 000080f4 0000f4 000013 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 00008108 000108 000020 00 A 0 0 4
[ 3] .hash HASH 00008128 000128 000040 04 A 4 0 4
[ 4] .dynsym DYNSYM 00008168 000168 0000b0 10 A 5 1 4
[ 5] .dynstr STRTAB 00008218 000218 0000ae 00 A 0 0 1
[ 6] .gnu.version VERSYM 000082c6 0002c6 000016 02 A 4 0 2
[ 7] .gnu.version_r VERNEED 000082dc 0002dc 000020 00 A 5 1 4
[ 8] .rel.dyn REL 000082fc 0002fc 000028 08 A 4 0 4
[ 9] .rel.plt REL 00008324 000324 000020 08 A 4 11 4
[10] .init PROGBITS 00008344 000344 000014 00 AX 0 0 4
[11] .plt PROGBITS 00008358 000358 000044 04 AX 0 0 4
[12] .text PROGBITS 0000839c 00039c 000260 00 AX 0 0 4
[13] .fini PROGBITS 000085fc 0005fc 00000c 00 AX 0 0 4
[14] .rodata PROGBITS 00008608 000608 000010 00 A 0 0 4
[15] .eh_frame PROGBITS 00008618 000618 000004 00 A 0 0 4
[16] .ctors PROGBITS 0001061c 00061c 000008 00 WA 0 0 4
[17] .dtors PROGBITS 00010624 000624 000008 00 WA 0 0 4
[18] .jcr PROGBITS 0001062c 00062c 000004 00 WA 0 0 4
[19] .dynamic DYNAMIC 00010630 000630 0000c8 08 WA 5 0 4
[20] .got PROGBITS 000106f8 0006f8 000030 04 WA 0 0 4
[21] .data PROGBITS 00010728 000728 00000c 00 WA 0 0 4
[22] .bss NOBITS 00010734 000734 000004 00 WA 0 0 1
[23] .comment PROGBITS 00000000 000734 0001d5 00 0 0 1
[24] .debug_aranges PROGBITS 00000000 000910 000058 00 0 0 8
[25] .debug_info PROGBITS 00000000 000968 00019a 00 0 0 1
[26] .debug_abbrev PROGBITS 00000000 000b02 000020 00 0 0 1
[27] .debug_line PROGBITS 00000000 000b22 000141 00 0 0 1
[28] .shstrtab STRTAB 00000000 000c63 000103 00 0 0 1
[29] .symtab SYMTAB 00000000 001240 000780 10 30 92 4
[30] .strtab STRTAB 00000000 0019c0 00036c 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00008034 0x00008034 0x000c0 0x000c0 R E 0x4
INTERP 0x0000f4 0x000080f4 0x000080f4 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x00008000 0x00008000 0x0061c 0x0061c R E 0x8000
LOAD 0x00061c 0x0001061c 0x0001061c 0x00118 0x0011c RW 0x8000
DYNAMIC 0x000630 0x00010630 0x00010630 0x000c8 0x000c8 RW 0x4
NOTE 0x000108 0x00008108 0x00008108 0x00020 0x00020 R 0x4

Section to Segment mapping:
Segment Sections...
00
01 .interp
02
.interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r
.rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame
03 .ctors .dtors .jcr .dynamic .got .data .bss
04 .dynamic
05 .note.ABI-tag

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.