ESP_LOGI
间隔 163813
微秒,平均下来一次 float 计算要 1 微秒,与芯片性能严重不符。请问是什么原因导致的呢?#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#define M2T(X) ((unsigned int)(X) / portTICK_PERIOD_MS) // ms to tick
#include "esp_random.h"
#include <sys/time.h>
static const char *TAG = "main";
#define dataLen 14400
void makeMatrixUint8(uint8_t *buf, int len)
{
for (int i = 0; i < len; i++)
{
esp_fill_random(&buf[i], sizeof(uint8_t));
}
}
void makeMatrixFloat(float *buf, int len)
{
for (int i = 0; i < len; i++)
{
esp_fill_random(&buf[i], sizeof(float));
}
}
static void testTask()
{
uint8_t *testData1 = (uint8_t *)malloc(sizeof(uint8_t) * dataLen);
float *testData2 = (float *)malloc(sizeof(float) * dataLen);
struct timeval tv_d0;
struct timeval tv_d1;
while (1)
{
makeMatrixUint8(testData1, dataLen);
makeMatrixFloat(testData2, dataLen);
gettimeofday(&tv_d0, NULL);
for (int t = 0; t < 10; t++)
{
for (int i = 0; i < dataLen; i++)
{
testData2[i] = testData1[i] * 0.3;
}
}
gettimeofday(&tv_d1, NULL);
ESP_LOGI(TAG, "%lu", 1000000 * (tv_d1.tv_sec - tv_d0.tv_sec) + (tv_d1.tv_usec - tv_d0.tv_usec));
vTaskDelay(1);
}
}
void app_main()
{
xTaskCreate(testTask, "servoTask", 1024 * 4, NULL, tskIDLE_PRIORITY, NULL);
}
1
zk8802 2023-04-12 07:06:37 +08:00
看一下编译生成的二进制代码,里面的浮点运算是软件模拟的浮点指令还是硬件浮点指令?
|
2
geekzjj 2023-04-12 08:06:05 +08:00 via Android
gettimeofday 以及 log 函数本身的性能损耗测过吗?
|
3
biggates 2023-04-12 10:46:39 +08:00
你用 `esp_fill_random()` 的话,是不是只要把整个 `buf` fill 一次就行了,不需要循环去 fill 每个元素?
|
4
biggates 2023-04-12 10:53:15 +08:00
原文: This function automatically busy-waits to ensure enough external entropy has been introduced into the hardware RNG state, before returning a new random number. This delay is very short (always less than 100 CPU cycles). 所以你 dataLen 14400 的时候,每次 delay 加起来就很大了。src: https://docs.espressif.com/projects/esp-idf/zh_CN/v4.4.4/esp32/api-reference/system/random.html#_CPPv410esp_randomv
|
5
Leon6868 OP |
6
misdake 2023-04-13 09:40:16 +08:00 via Android
0.3 改成 0.3f
|
7
misdake 2023-04-13 09:48:17 +08:00 via Android 3
godbolt 反汇编: https://godbolt.org/z/or71efds8
double 乘法还是走的软件模拟,类型转换也是。会先后调用 floatsidf muldf3 truncdfsf2 这三个函数,所以很慢吧。 改成 0.3f 之后,就全是正常指令了,float.s mul.s 这类,不需要调用其他方法。 |
8
misdake 2023-04-13 10:00:15 +08:00 via Android 1
esp32-s3 模拟: https://wokwi.com/projects/361855375362930689
0.3 打印的时间是 1891678 0.3f 打印的时间是 166518 性能提高 10 倍 |
9
misdake 2023-04-13 10:08:48 +08:00 via Android 1
作为对比,去掉* 0.3 的代码,只做类型转换 testData2[i] = testData1[i],模拟器打印时间是 116627 ,和 0.3f 的版本相比性能提升幅度很合理
|