• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

RTL8710BN FPU

pvvx

Активный участник сообщества
Для начала:
10 полезных советов по использованию блока с плавающей запятой на процессоре Arm Cortex-M4

Далее - где взять какой стандартный бенчмарк FPU на СИ?

-----
Не найдя ничего подходящего, пришлось сравнить с ESP-32 и из темы

Unexpectedly low floating-point performance in C
с кодом и данными от ESP32 floating-point performance на STM32F767 216 MHz и ESP-32 240 MHz.
Код:
[/SIZE]
#include "debug.h"
volatile float f1 = 1.11111111111111111111;
volatile float f2 = 4.44444444444444444444;

volatile float fSum;
volatile float fSqr;
volatile float fMul;
volatile float fDiv;
volatile float fPow;
volatile float fSin;
volatile float fLst;

volatile double d1 = 1.11111111111111111111;
volatile double d2 = 4.44444444444444444444;

volatile double dSum;
volatile double dSqr;
volatile double dMul;
volatile double dDiv;
volatile double dPow;
volatile double dSin;
volatile double dLst;
// Quick hack to print floating-point values
static char *f2s(char *buf, float f);
static char *d2s(char *buf, double f);
char gBuf[256], gBuf2[256];

void setup() {
   Serial.begin();
   sys_info();
   init_cyccnt(); // запустить счетчик тактов CPU
}
void loop() {
    while (1) {
        volatile unsigned int tt0 = get_cyccnt();     

        // 236ns
        fSum = f1 + f2;
        // 4.6us
        fSqr = sqrtf(f1);
        // 226ns
        fMul = f1 * f2;
        // 424ns
        fDiv = f1 / f2;
        // 15.1us
        fPow = powf(f1, f2);
        // 1.1us
        fSin = sinf(f1);
       
        volatile unsigned int tt1 = get_cyccnt();     

        // 490ns
        dSum = d1 + d2;
        // 4.2us
        dSqr = sqrt(d1);
        // 680ns
        dMul = d1 * d2;
        // 2.2us
        dDiv = d1 / d2;
        // 71us
        dPow = pow(d1, d2);
        // 8.8us
        dSin = sin(d1);

        volatile unsigned int tt2 = get_cyccnt();
        volatile unsigned int tt3 = get_cyccnt();
       
        printf("--------- float  ---------------------------------------\r\n");
тут печать значений, чтобы их не оптимизнул компилятор - вырезал для краткости
        printf("\r\nCPU tick = %u, CLK = %u Hz\r\n", tt1-tt0, get_cpuclk());
       
        printf("--------- double ---------------------------------------\r\n");
тут печать значений, чтобы их не оптимизнул компилятор - вырезал для краткости
        printf("\r\nCPU tick = %u, CLK = %u Hz\r\n", tt2-tt1, get_cpuclk());
        printf("\r\nTst tick = %u\r\n", tt3-tt2);
        delay(100);
        tt2 = get_cyccnt();
        delay(100);
        tt3 = get_cyccnt();
        printf("\r\nTst tick 100 ms = %u\r\n\r\n", tt3-tt2);
        delay(100);
    }
}
Код:
ROM:[V0.1]
FLASHRATE:4
BOOT TYPE:0 XTAL:40000000
IMG1 DATA[1112:10002000]
IMG1 ENTRY[800043b:100021dd]

CLK CPU         125000000 Hz
RAM heap        181064 bytes
--------- float  ---------------------------------------
CPU tick = 26553, CLK = 125000000 Hz
--------- double ---------------------------------------
CPU tick = 69434, CLK = 125000000 Hz
Tst tick = 182
Tst tick 100 ms = 12207053
--------- float  ---------------------------------------
CPU tick = 1606, CLK = 125000000 Hz
--------- double ---------------------------------------
CPU tick = 29025, CLK = 125000000 Hz
Tst tick = 14
Tst tick 100 ms = 12206999
....

Итого:
Первый заход идет с подгрузкой исполняемого кода из Flash.
Выполнение тестовой последовательности float: 26553 тактов, double: 69434.
Double смотреть смысла нет - они софт.
Выполнение последующих тестовых последовательностей уже из "кэш" flash:
float: 1606 тактов, double: 29025.
Время на получение счетчика тактов CPU = 14 тактов.
Из этого выходит, что тестовая последовательность float выполняется за (1606-14)/125000000=0.000012736 сек (12.736 мкс).

Сравнение:

  • 10 650 ns STM32F767 216 MHz
  • 12 736 ns RTL8710BN 125 MHz
  • 21 686 ns ESP-32 240 MHz (с сайта ESP), Уточнение: ESP-32 240 MHz от 6 233 до 119 438 ns (зависит от погоды).
Что-то в этом деле не так, но cо сломанным FPU у ESP-32 сравнивать смыслу нет (там обычный CPU софт-число-дробилкой справиться быстрее)...
 
Последнее редактирование:

Юрий Ботов

Moderator
Команда форума
Что то не вяжутся первые два результата с моим пониманием... stm32f767 с реальным sram и подключаемым кэшем и rtl с псевдо-sram и без кэша(я не видел упоминания о нем)... у второго производительность выше почти в 2 раза? esp32 то понятно...
Уточните какие условия были при сравнении с stm.
 

pvvx

Активный участник сообщества
Уточните какие условия были при сравнении с stm.
Условия взяты у автора кода. Из https://www.esp32.com/download/file.php?id=344&sid=d75100e59938ad8bc0daef2bb73d2987
Поэтому и написал
Что-то в этом деле не так
У автора указано 50+390+50+160+7400+2600 ns (10650 ns) на STM32F767 216 MHz
-----
stm32f767 с реальным sram и подключаемым кэшем и rtl с псевдо-sram и без кэша(я не видел упоминания о нем)...
Что за "псевдо-sram"?
И зачем кэш на проц работающий из SRAM? У RTL нет внутренней параллельной Flash на 70 ns и организовывать кэш для проца не требуется. Про "кэш" (XIP) SPI flash написано в документации - 32 килобайта и замеры первого прохода до её заполнения я указал. У SRAM и ROM нет проблем работы на 125 MHz.
SPI Flash работает на 100 MHz QIO. На XIP идет что-то более 250 MHz... "Кэша" SPI-Flash и большей части кода API в ROM достаточно для работы WiFi дров и приложения - при работе модуля не наблюдается обращений к SPI-Flash на осциллографе, к примеру в проекте Web-свалки. Только при старте.
esp32 то понятно...
И что там понятно? Не могли бы уточнить?
В теме форума по ESP32 ничего не написано, почему и что. Только одна ерунда от kolban про gpio и ESP_igrr, связанная с переключением контекста в RTOS, c подключением туда доп.регистров FPU... что является стандартом в RTOS.
Мой тест в RTOS, вообще в Arduino для RTL8710BN.
Время считает правильно, даже указывает ошибку установки таймера на тики RTOS как отношение 32 к 32.768 (Tst tick 100 ms = 12206999, при CLK 125000000. 32.768*12206999/12500000 = 31.999915).
Можно сделать замер каждой отдельной команды, но результат не изменится.
------
Измерять всякой ерундой нет желания. И главный вопрос темы: где взять какой стандартный бенчмарк FPU на СИ?
Тогда и проганю тест на всех перечисленных CPU. Есть все в наличии и не вижу сложностей получить результаты в кол-ве тактов CPU...
 
Последнее редактирование:
Сверху Снизу