Edge Impulse ML模型从Arduino IDE移植到ESP-IDF(ESP32-CAM)后推理速度慢5倍的排查求助
Edge Impulse ML模型从Arduino IDE移植到ESP-IDF(ESP32-CAM)后推理速度慢5倍的排查求助
我最近在把Edge Impulse生成的ML模型从Arduino移植到ESP-IDF环境(用于ESP32-CAM设备)时,遇到了一个头疼的性能问题:
- 在Arduino环境下,模型推理仅需**~1300ms**(编译优化为
-Os) - 但在ESP-IDF环境下,同样用
-Os优化,推理耗时居然高达**~6600ms**
我尝试把ESP-IDF的编译优化调到-O2,速度能提升到~2000ms,但还是远不如Arduino的表现。关键是两个环境的CPU频率都设置为240MHz,我已经排查了很多点,但始终找不到问题所在,想请大家帮忙看看哪里可能漏了。
已完成的排查步骤
我已经逐一排查了以下可能的影响因素:
- CPU算力与线程环境验证:
用包含矩阵运算的测试样例(涉及volatile浮点数和整数)验证两个环境的CPU计算能力,结果几乎一致;同时确认模型推理都运行在Core1,线程优先级、CPU频率完全相同。 - TensorFlow Lite配置统一:
两个环境都添加了-DTF_LITE_STATIC_MEMORY编译宏,确保TensorFlow Lite使用静态内存分配。 - 并行与多线程排查:
确认两个环境都禁用了OPEN_MP,没有并行执行的额外逻辑干扰。 - 编译器与编译参数对齐:
尝试切换编译器,排查是否是libc或编译器版本的问题;同时尽可能对齐Arduino的编译参数,下面是两个环境的编译参数对比:
Arduino编译参数
COLLECT_GCC_OPTIONS='-c' '-mlongcalls' '-Wno-frame-address' '-ffunction-sections' '-fdata-sections' '-Wno-error=unused-function' '-Wno-error=unused-variable' '-Wno-error=unused-but-set-variable' '-Wno-error=deprecated-declarations' '-Wno-unused-parameter' '-Wno-sign-compare' '-Wno-enum-conversion' '-gdwarf-4' '-ggdb' '-freorder-blocks' '-Wwrite-strings' '-fstack-protector' '-fstrict-volatile-bitfields' '-fno-jump-tables' '-fno-tree-switch-conversion' '-std=gnu++23' '-fexceptions' '-fno-rtti' '-w' '-Os' '-v' '-w' '-E' '-CC' '-D' 'F_CPU=240000000L' '-D' 'ARDUINO=10607' '-D' 'ARDUINO_ESP32_DEV' '-D' 'ARDUINO_ARCH_ESP32' '-D' 'ARDUINO_BOARD="ESP32_DEV"' '-D' 'ARDUINO_VARIANT="esp32"' '-D' 'ARDUINO_PARTITION_huge_app' '-D' 'ARDUINO_HOST_OS="windows"' '-D' 'ARDUINO_FQBN="esp32:esp32:esp32cam:CPUFreq=240,FlashFreq=80,FlashMode=qio,PartitionScheme=huge_app,DebugLevel=none,EraseFlash=none"' '-D' 'ESP32' '-D' 'CORE_DEBUG_LEVEL=0' '-D' 'BOARD_HAS_PSRAM' '-mfix-esp32-psram-cache-issue' '-mfix-esp32-psram-cache-strategy=memw' '-D' 'ARDUINO_USB_CDC_ON_BOOT=0' '-D' 'ESP_PLATFORM' '-D' 'IDF_VER="v5.1.4-497-gdc859c1e67-dirty"' '-D' 'MBEDTLS_CONFIG_FILE="mbedtls/esp_config.h"' '-D' 'SOC_MMU_PAGE_SIZE=CONFIG_MMU_PAGE_SIZE' '-D' 'UNITY_INCLUDE_CONFIG_H' '-D' '_GNU_SOURCE' '-D' '_POSIX_READER_WRITER_LOCKS' '-D' 'configENABLE_FREERTOS_DEBUG_OCDAWARE=1' '-D' 'TF_LITE_STATIC_MEMORY' '-I'
ESP-IDF编译参数
C:\Espressif\tools\xtensa-esp32-elf\esp-12.2.0_20230208\xtensa-esp32-elf\bin\xtensa-esp32-elf-g++.exe -mlongcalls -Wno-frame-address -DNDEBUG -fdiagnostics-color=always -Wno-unused-variable -Wno-deprecated-declarations -Wno-missing-field-initializers -Wno-maybe-uninitialized -Wno-error=uninitialized -DTF_LITE_STATIC_MEMORY -mlongcalls -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -fno-jump-tables -fno-tree-switch-conversion -fno-rtti -w -Wall -Werror=all -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=unused-but-set-variable -Wno-error=deprecated-declarations -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-enum-conversion -gdwarf-4 -ggdb -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-strategy=memw -Os -freorder-blocks -fmacro-prefix-map=path -fmacro-prefix-map=other_path -DconfigENABLE_FREERTOS_DEBUG_OCDAWARE=1 -std=gnu++2b -fno-exceptions -DESP32=ESP32 -MD -MT file.cpp.obj -MF file.cpp.obj.d -o file.cpp.obj -c file.cpp
最让我困惑的是,Arduino用-Os就能达到最优表现,但ESP-IDF即使升到-O2还是追不上,这说明可能不是单纯的优化等级问题,而是某个编译配置或环境差异导致的。
实在想不到还有什么地方没查了,有没有朋友遇到过类似的问题?或者能从编译参数、环境配置里发现什么我忽略的点?万分感谢!
备注:内容来源于stack exchange,提问作者A.KYROU
相关产品推荐
相关产品推荐

