Check FPU function using Cos & Sin calculation

main.cpp

Committer:
kenjiArai
Date:
2021-01-25
Revision:
2:742afd5cf29f
Parent:
1:a8ba417b1717

File content as of revision 2:742afd5cf29f:

/*
 * Check FPU function using Cos & Sin calculation
 *
 * Copyright (c) 2017,'21 Kenji Arai / JH1PJL
 *  http://www7b.biglobe.ne.jp/~kenjia/
 *  https://os.mbed.com/users/kenjiArai/
 *      Modify:     August    31st, 2017
 *      Revised:    January   25th, 2021
 */

/*==============================================================================
    -------------------- My boards result -------------------------------
                         STM32F446RE   STM32F411RE   STM32H743ZI2
    Sys Clock            180 MHz       100 MHz       480 MHz
    double               23844 nS      39710 nS      1149 ns
    float                1085 nS       1954 nS       375 ns
    ratio(double/float)  21.98         20.32         3.06

    ratio(F446/H743 double)            20.75
    ratio(F446/H743 float)             2.89
    ratio(F411/F446 double)            1.67
    ratio(F411/F446 float)             1.80
  ============================================================================*/

//  Include --------------------------------------------------------------------
#include "mbed.h"
#include "uart_as_stdio.h"

//  Definition -----------------------------------------------------------------
#define PI 3.14159265
#define BUF_SIZE    7000

//  Constractor ----------------------------------------------------------------
Timer   t;

//  RAM ------------------------------------------------------------------------
float   buf0[BUF_SIZE];
double  buf1[BUF_SIZE];

//  ROM / Constant data --------------------------------------------------------

//  Function prototypes --------------------------------------------------------
void test_FPU_0(float  *buf0);
void test_FPU_1(double *buf1);
extern void print_revision(void);

//------------------------------------------------------------------------------
//  Control Program
//------------------------------------------------------------------------------
int main()
{
    print_revision();
    printf("\r\nSystem Clock = %d Hz\r\n", HAL_RCC_GetSysClockFreq());
    // Check FPU settings
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    // Set bits 20-23 to enable CP10 and CP11 coprocessors
    // SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
    // Mbed compiler set CP10 and CP11 Full Access
    printf("Use FPU function (compiler enables FPU)\r\n");
    printf("SCB->CPACR(0x%08x) = 0x%08x\r\n",
           (uint32_t)&SCB->CPACR, SCB->CPACR);
#else
#warning "NOT use FPU in your setting"
#endif
    printf("Buf size in RAM = %d + %d = %d bytes\r\n",
           sizeof(buf0), sizeof(buf1), sizeof(buf0) + sizeof(buf1));
    printf("Repeat number = %d\r\n", BUF_SIZE);
    printf("\r\nHit any key then show buffer content\r\n");
    printf("Following time is average calculate time Sin()+Cos()\r\n");
    printf("  (float)       (double)\r\n");
    while (true) {
        uint32_t t0, t1;

        t.reset();
        t.start();
        test_FPU_0(buf0);
        t0 = t.elapsed_time().count();
        t.reset();
        t.start();
        test_FPU_1(buf1);
        t1 = t.elapsed_time().count();
        printf("t0 =%.3f uS, t1 =%.3f uS\r\n",
               (double)t0 / (double)BUF_SIZE, (double)t1 / (double)BUF_SIZE);
        if (readable()) {
            for (uint16_t n = 0; n < BUF_SIZE; n++) {
                printf("%+8.6f,%+8.6lf,%+8.6lf\r\n",
                       buf0[n], buf1[n], (double)buf0[n] - buf1[n]);
            }
            while (readable()) {
                getc();
            }
        }
        ThisThread::sleep_for(1s);
    }
}

void test_FPU_0(float *buf0)
{
    int32_t i;
    volatile float d, d0, d1;
    float step;

    step = ((2.0f * PI) + 0.1f) / (float)BUF_SIZE;
    d = 0.0f;
    for(i = 0; i < BUF_SIZE; i++) {
        d0 = sin(d);
        d1 = cos(d);
        d += step;
        buf0[i] = d0;
    }
}

void test_FPU_1(double *buf1)
{
    int32_t i;
    volatile double d, d0, d1;
    double step;

    step = ((2.0 * PI) + 0.1) / (double)BUF_SIZE;
    d = 0.0;
    for(i = 0; i < BUF_SIZE; i++) {
        d0 = sin(d);
        d1 = cos(d);
        d += step;
        buf1[i] = d0;
    }
}