Check FPU function using Cos & Sin calculation

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Check FPU function using Cos & Sin calculation
00003  *
00004  * Copyright (c) 2017,'21 Kenji Arai / JH1PJL
00005  *  http://www7b.biglobe.ne.jp/~kenjia/
00006  *  https://os.mbed.com/users/kenjiArai/
00007  *      Modify:     August    31st, 2017
00008  *      Revised:    January   25th, 2021
00009  */
00010 
00011 /*==============================================================================
00012     -------------------- My boards result -------------------------------
00013                          STM32F446RE   STM32F411RE   STM32H743ZI2
00014     Sys Clock            180 MHz       100 MHz       480 MHz
00015     double               23844 nS      39710 nS      1149 ns
00016     float                1085 nS       1954 nS       375 ns
00017     ratio(double/float)  21.98         20.32         3.06
00018 
00019     ratio(F446/H743 double)            20.75
00020     ratio(F446/H743 float)             2.89
00021     ratio(F411/F446 double)            1.67
00022     ratio(F411/F446 float)             1.80
00023   ============================================================================*/
00024 
00025 //  Include --------------------------------------------------------------------
00026 #include "mbed.h"
00027 #include "uart_as_stdio.h"
00028 
00029 //  Definition -----------------------------------------------------------------
00030 #define PI 3.14159265
00031 #define BUF_SIZE    7000
00032 
00033 //  Constractor ----------------------------------------------------------------
00034 Timer   t;
00035 
00036 //  RAM ------------------------------------------------------------------------
00037 float   buf0[BUF_SIZE];
00038 double  buf1[BUF_SIZE];
00039 
00040 //  ROM / Constant data --------------------------------------------------------
00041 
00042 //  Function prototypes --------------------------------------------------------
00043 void test_FPU_0(float  *buf0);
00044 void test_FPU_1(double *buf1);
00045 extern void print_revision(void);
00046 
00047 //------------------------------------------------------------------------------
00048 //  Control Program
00049 //------------------------------------------------------------------------------
00050 int main()
00051 {
00052     print_revision();
00053     printf("\r\nSystem Clock = %d Hz\r\n", HAL_RCC_GetSysClockFreq());
00054     // Check FPU settings
00055 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
00056     // Set bits 20-23 to enable CP10 and CP11 coprocessors
00057     // SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
00058     // Mbed compiler set CP10 and CP11 Full Access
00059     printf("Use FPU function (compiler enables FPU)\r\n");
00060     printf("SCB->CPACR(0x%08x) = 0x%08x\r\n",
00061            (uint32_t)&SCB->CPACR, SCB->CPACR);
00062 #else
00063 #warning "NOT use FPU in your setting"
00064 #endif
00065     printf("Buf size in RAM = %d + %d = %d bytes\r\n",
00066            sizeof(buf0), sizeof(buf1), sizeof(buf0) + sizeof(buf1));
00067     printf("Repeat number = %d\r\n", BUF_SIZE);
00068     printf("\r\nHit any key then show buffer content\r\n");
00069     printf("Following time is average calculate time Sin()+Cos()\r\n");
00070     printf("  (float)       (double)\r\n");
00071     while (true) {
00072         uint32_t t0, t1;
00073 
00074         t.reset();
00075         t.start();
00076         test_FPU_0(buf0);
00077         t0 = t.elapsed_time().count();
00078         t.reset();
00079         t.start();
00080         test_FPU_1(buf1);
00081         t1 = t.elapsed_time().count();
00082         printf("t0 =%.3f uS, t1 =%.3f uS\r\n",
00083                (double)t0 / (double)BUF_SIZE, (double)t1 / (double)BUF_SIZE);
00084         if (readable()) {
00085             for (uint16_t n = 0; n < BUF_SIZE; n++) {
00086                 printf("%+8.6f,%+8.6lf,%+8.6lf\r\n",
00087                        buf0[n], buf1[n], (double)buf0[n] - buf1[n]);
00088             }
00089             while (readable()) {
00090                 getc();
00091             }
00092         }
00093         ThisThread::sleep_for(1s);
00094     }
00095 }
00096 
00097 void test_FPU_0(float *buf0)
00098 {
00099     int32_t i;
00100     volatile float d, d0, d1;
00101     float step;
00102 
00103     step = ((2.0f * PI) + 0.1f) / (float)BUF_SIZE;
00104     d = 0.0f;
00105     for(i = 0; i < BUF_SIZE; i++) {
00106         d0 = sin(d);
00107         d1 = cos(d);
00108         d += step;
00109         buf0[i] = d0;
00110     }
00111 }
00112 
00113 void test_FPU_1(double *buf1)
00114 {
00115     int32_t i;
00116     volatile double d, d0, d1;
00117     double step;
00118 
00119     step = ((2.0 * PI) + 0.1) / (double)BUF_SIZE;
00120     d = 0.0;
00121     for(i = 0; i < BUF_SIZE; i++) {
00122         d0 = sin(d);
00123         d1 = cos(d);
00124         d += step;
00125         buf1[i] = d0;
00126     }
00127 }