2017年1月11日水曜日

Nucleo F446REとNucleo F401REの浮動小数点演算比較

以前F401REでやった浮動小数点演算のサイン波テーブル生成のプログラムでF401REとF446REの実行時間を比較してみた。

F446REの駆動クロックが180MHzで、F401REの駆動クロックが84MHzなので単純に割り算すると

2.142857143

になる。

プログラムは前回と同じもので比較。

main.cpp
#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());  
 }  

単精度浮動小数点演算


TABLE_LENGTH F401RE float (us) F446RE float (us) F401RE vs F446RE
512 372 181 2.055248619
1024 743 359 2.069637883
2048 1486 718 2.069637883
4096 2972 1433 2.073970691
8192 5943 2866 2.073621773




倍精度浮動小数点演算


TABLE_LENGTH F401RE double (us) F446RE double (us) F401RE vs F446RE
512 6753 3275 2.061984733
1024 13550 7473 1.813194166
2048 27129 14968 1.812466595
4096 54356 29957 1.814467403
8192 108877 59936 1.816554325



F401REは、単精度浮動小数点演算(float)は前回と同じ結果だが、倍精度浮動小数点数演算(double)はかなり結果が良くなっている。mbedのNucleoの浮動小数点数演算のライブラリがチューニングされているのかも?

float vs double


TABLE_LENGTH F401RE F446RE F401RE vs F446RE
512 18.15322581 18.09392265 1.003277518
1024 18.23687752 20.81615599 0.87609247
2048 18.256393 20.84679666 0.875740926
4096 18.28936743 20.90509421 0.874876107
8192 18.32020865 20.91277041 0.876029732

単精度と倍精度の比較では、F401REで約18倍、F446REで約21倍、単精度のほうが高速のようだ。