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