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);
}
|      1zk8802      2023-04-12 07:06:37 +08:00 看一下编译生成的二进制代码,里面的浮点运算是软件模拟的浮点指令还是硬件浮点指令? | 
|      2geekzjj      2023-04-12 08:06:05 +08:00 via Android gettimeofday 以及 log 函数本身的性能损耗测过吗? | 
|      3biggates      2023-04-12 10:46:39 +08:00 你用 `esp_fill_random()` 的话,是不是只要把整个 `buf` fill 一次就行了,不需要循环去 fill 每个元素? | 
|      4biggates      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 | 
|  |      5Leon6868 OP | 
|      6misdake      2023-04-13 09:40:16 +08:00 via Android 0.3 改成 0.3f | 
|      7misdake      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 这类,不需要调用其他方法。 | 
|      8misdake      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 倍 | 
|      9misdake      2023-04-13 10:08:48 +08:00 via Android  1 作为对比,去掉* 0.3 的代码,只做类型转换 testData2[i] = testData1[i],模拟器打印时间是 116627 ,和 0.3f 的版本相比性能提升幅度很合理 |