ARM浮點運算

原帖地址:http://blog.sina.com.cn/s/blog_602f87700100r5xe.html

一:早期ARM上的浮點模擬器:

早期的ARM沒有協處理器,所以浮點運算是由CPU來模擬的,即所需浮點運算均在浮點運算模擬器(float math emulation)上進行,需要的浮點運算,常要耗費數千個循環才能執行完畢,因此特別緩慢。

直到今天,在ARM Kernel配置時,都有如下選項:

Floating point emulation  --->

[ ] NWFPE math emulation

[ ] FastFPE math emulation (EXPERIMENTAL) 

在這裏,可以配置ARM 浮點模擬器。

 

浮點模擬器 模擬浮點是利用了undefined instrction handler,這麼做帶來的後果是帶來極頻繁的exception,大大增加中斷延遲,降低系統實時性。

 

二:軟浮點技術:

軟浮點支持是由交叉工具鏈提供的功能,與Linux內核無關。當使用軟浮點工具鏈編譯浮點操作時,編譯器會用內聯的浮點庫替換掉浮點操作,使得生成的機器碼完全不含浮點指令,但是又能夠完成正確的浮點操作。

 

三:浮點協處理器:

在較新版本的ARM中,可以添加協處理器。 一些ARM CPU爲了更好的處理浮點計算的需要,添加了浮點協處理器。

並定義了浮點指令集。 如果不存在實際的硬件,則這些指令被截獲並由浮點模擬器模塊(FPEmulator)來執行。

 

 

四: 硬件浮點協處理器以及對應指令集的使用:

這裏Sam是這樣理解的:

想要使用硬件浮點協處理器來幫助運算Application中的浮點運算。需要以下幾個前提條件:

1. Kernel中設置支持 硬件協處理器。

2. 編譯器支持將浮點運算翻譯成硬件浮點運算指令。

 

1. Kernle的支持:

如果Kernel不支持浮點協處理器,則因爲協處理器寄存器等使用權限等問題,協處理器對應指令無法運行。

網絡上有位高手指出:

CP15 c1 協處理器訪問控制寄存器,這個寄存器規定了用戶模式和特權對協處理器的訪問權限。我們要使用VFP當然要運行用戶模式訪問CP10和CP11。
另外一個寄存器是VFP的FPEXC Bit30這是VFP功能的使用位。
其實操作系統在做了這兩件事情之後,用戶程序就可以使用VFP了。當然,Kernel 除了這2件事外,還處理了其他一些事情。

 

Sam看了看Kernel中對應代碼,發現是彙編後就放棄繼續研究了。

Floating point emulation  --->
[*] VFP-format floating point maths

Include VFP support code in the kernel. This is needed IF your hardware includes a VFP unit.

 

2. 編譯器指定浮點指令:

編譯器可以顯式指定將浮點運算翻譯成何種浮點指令。

 

如果編譯器支持軟浮點,則其可能會將浮點運算翻譯成編譯器中自帶的浮點庫。則不會有真正的浮點運算。

否則,可以翻譯成FPA(Floating Point Accelerator)指令。 FPA指令再去查看是否有浮點模擬器。

還可以將浮點運算指定爲VFP(vector floating point)指令。

 

 

五. 編譯器指定編譯硬浮點指令:

Sam有個測試程序,測試CPU浮點性能。例如:浮點加減乘除等運算的時間長度:

 

float src_mem_32[1024] = {1.024};


float dst_mem_32[1024] = {0.933};

 

for(j = 0; j < 1024; j++)
{
     for(i = 0; i < 1024; i++)
     {
          src_32 = src_mem_32[i] + dst_mem_32[i];
     }
}

通過printf 計算前後毫秒數的差值來看計算能力。

 

編譯:

arm-hisiv200-linux-gcc -c   -Wall fcpu.c -o fcpu.o

arm-hisiv200-linux-gcc fcpu.o -o FCPU -L./

運行,則得到32位浮點數加1024次所需要時間。

 

如果要使用VFP呢?

arm-hisiv200-linux-gcc -c   -Wall -mfpu=vfp -mfloat-abi=softfp  fcpu.c -o fcpu.o

arm-hisiv200-linux-gcc -Wall -mfpu=vfp -mfloat-abi=softfp   fcpu.o -o FCPU -L./

則運行後發現,所需要時間幾乎減小了一半。 說明還是非常有效果的。

關於-mfpu   -mfloat-abi講解:見附錄2。 

 

另外,如何才能在直觀的檢查出是否使用VFP呢?

可以通過察看編譯出的ASM程序得到結論。

 

#arm-hisiv200-linux-objdump -d fcpu.o

00000000 <test_F32bit_addition>:
   0:   e52db004        push    {fp}            ; (str fp, [sp, #-4]!)
   4:   e28db000        add     fp, sp, #0
   8:   e24dd00c        sub     sp, sp, #12
   c:   e3a03000        mov     r3, #0
  10:   e50b300c        str     r3, [fp, #-12]
  14:   e3a03000        mov     r3, #0
  18:   e50b3008        str     r3, [fp, #-8]
  1c:   e3a03000        mov     r3, #0
  20:   e50b3008        str     r3, [fp, #-8]
  24:   ea000017        b       88 <test_F32bit_addition+0x88>
  28:   e3a03000        mov     r3, #0
  2c:   e50b300c        str     r3, [fp, #-12]
  30:   ea00000d        b       6c <test_F32bit_addition+0x6c>
  34:   e51b200c        ldr     r2, [fp, #-12]
  38:   e59f3064        ldr     r3, [pc, #100]  ; a4 <test_F32bit_addition+0xa4>
  3c:   e0831102        add     r1, r3, r2, lsl #2
  40:   ed917a00        

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章