2016年2月12日金曜日

NUCLEO-F401RE(Cortex-M4)とPSoC 5LP(Cortex-M3)の浮動小数点演算比較

小ネタ実験です。

NUCLEO-F401REに載っているMPUはSTM32F401でCortex-M4ベースでFPUが搭載されている。しかも1,500円@秋月とPSoC 5LP Prototyping Kit(Cortex-M3ベース)と同じ値段だ。

このあいだPSoC 5LPで浮動小数点演算をしてサイン波のテーブルを作成してみたが、FPU付きのNUCLEO-F401REでも同じことをして比較してみた。

NUCLEOはmbedのオンラインコンパイラ使った。

 #include "mbed.h"  
   
 //------------------------------------  
 // Hyperterminal configuration  
 // 9600 bauds, 8-bit data, no parity  
 //------------------------------------  
 #include <math.h>  
   
 #define M_PI      (3.14159265358979323846) /* pi double*/  
 #define M_PI_f     (3.1415926f) /* pi float */  
 #define TABLE_LENGTH  (8192)  
   
 Serial pc(SERIAL_TX, SERIAL_RX);  
 Timer timer0;  
 uint8_t waveTable_0[TABLE_LENGTH];  
   
 void genSineTable_double(uint8_t *table, int length)   
 {   
   int i;   
   int16_t v;   
   int8_t* p8;   
   for (i = 0; i < length / 2; i++) {   
      v = (int16_t)(sin(2.0 * M_PI * i * 2 / length) * 32767);   
      p8 = (int8_t *)&v;   
      table[i*2] = *(p8+1);   
      table[i*2+1] = *p8;   
   }   
 }  
   
 void genSineTable_float(uint8_t *table, int length)   
 {   
   int i;   
   int16_t v;   
   int8_t* p8;   
   for (i = 0; i < length / 2; i++) {   
      v = (int16_t)(sinf(2.0f * M_PI_f * i * 2 / length) * 32767);   
      p8 = (int8_t *)&v;   
      table[i*2] = *(p8+1);   
      table[i*2+1] = *p8;   
   }   
 }  
     
 int main() {  
   timer0.start();  
     
   // 単精度浮動小数点演算 (with FPU)  
   pc.printf("start float: TABLE_SIZE:%d\r\n", TABLE_LENGTH);  
   timer0.reset();  
   genSineTable_float(waveTable_0, TABLE_LENGTH);  
   pc.printf("%d\r\n", timer0.read_us());  
     
   // 倍精度浮動小数点演算  
   pc.printf("start double: TABLE_SIZE:%d\r\n", TABLE_LENGTH);  
   timer0.reset();  
   genSineTable_double(waveTable_0, TABLE_LENGTH);  
   pc.printf("%d\r\n", timer0.read_us());  
 }  
    


FPU付きだが単精度小数点数しか使えないらしいのでdouble型とfloat型の二通りでサイン波テーブルを生成。


TABLE_LENGTH Nucleo float (us) Nucleo double (us) float vs double PSoC 5LP(us)
512 372 18125 48.72311828 15280
1024 743 36255 48.79542396 29640
2048 1486 72718 48.93539704 58400
4096 2972 145631 49.00100942 116000
8192 5943 291349 49.02389366 230000


比較すると、floatだとNUCLEO-F401REが圧倒的に速い。

PSoC 5LPのコードは今回のものと少し違うが、double型で計算している。double型(FPUなし)だとM3のPSoC 5LPの方が若干速い結果になった。

動作クロックはPSoC5LPが72MHz、NUCLEO-F401REは84MHz。

double型(FPUなし)での比較はM3もM4も大差ないというぐらいの認識で(^q^;


メモ:


NucleoというかSTM32はmbed以外にもSTM32ネイティブ(?)のコンパイラがあってオフィシャルではIARとかの有償(企業向)のものが推奨されている。

無償ではCooCox CoIDEというのがある(GCC based IDEと書かれているのはこれかな?)

STM32 Cubeというライブラリもあるみたいで、よくわかりません。