当前位置: 首页> 游戏> 评测 > 手机建站服务_自己可以做微信公众号吗_seo模板建站_网络营销推广微信hyhyk1效果好

手机建站服务_自己可以做微信公众号吗_seo模板建站_网络营销推广微信hyhyk1效果好

时间:2025/7/12 15:59:31来源:https://blog.csdn.net/espressif/article/details/144514772 浏览次数:0次
手机建站服务_自己可以做微信公众号吗_seo模板建站_网络营销推广微信hyhyk1效果好

近年来,人工智能技术 (AI) 在图像识别、语音识别以及自然语言处理等领域取得了突破性进展,为嵌入式系统带来了更多的可能性。在将 AI 模型推理部署到 ESP32-P4 等嵌入式设备时,开发者总是希望能够持续优化模型的推理速度,以满足实时处理的需求。 

为了应对这一挑战,处理器指令拓展 (PIE, Processor Instruction Extensions) 应运而生。 PIE
是一组在 ESP32-S3/ESP32-P4 上新增的扩展指令,旨在提升特定 AI 与信号处理 (DSP, Digital Signal Processing) 算法的执行效率。基于单指令多数据 (SIMD, Single Instruction Multiple Data) 的设计理念,PIE 支持 8-bit、16-bit 以及 32-bit 的向量运算,能够显著提升数据运算效率。此外,对于乘法、位移、累加等运算指令,PIE 支持在数据计算的同时完成数据搬运操作,进一步提升单条指令的执行效率。 

ESP32-S3 与 ESP32-P4 的 PIE 差异: 

您可以在 ESP32-S3 和 ESP32-P4 上使用 PIE。虽然在这两种芯片上应用 PIE 的差别很小,但了解它们之间的细微差别对于优化您的应用性能至关重要: 

  • 指令架构差异:ESP32-S3 的 PIE 是基于 `TIE (Tensilica Instruction Extension)` 语言设计的,而 ESP32-P4 是支持标准的 `RV32IMAFCZc` 扩展,并包含一个自定义的 `Xhwlp` 硬件循环扩展,能够提高在硬件中执行 `for-loop` 的效率;
  • 内部结构差异:以乘法累加器 (MAC, Multiplication-accumulation) 为例,ESP32-S3 具有两个 160-bit 的累加器,而 ESP32-P4 具有两个 256-bit 的累加器; 
  • 指令格式差异:ESP32-S3 和 ESP32-P4 的 PIE 指令大体相似。但需要注意的是,ESP32-S3 的指令以 `ee` 开头,而 ESP32-P4 的指令以 `esp` 开头。此外,某些指令的功能或用法可能有所不同,详细信息请参阅相应的技术参考手册。 

上图显示了 PIE 中乘法累加器的数据路径,其中的虚线框突出显示了 ESP32-S3 和 ESP32-P4 之间的差异,蓝色代表 ESP32-S3,绿色代表 ESP32-P4。图中从左到右各块的详细说明如下: 

  • 内存 (Memory): 用于存储与快速访问数据;
  • 地址单元 (Address Unit): PIE 中的大部分指令都允许在一个周期内从 128-bit 的 Q 寄存器中并行加载或存储数据。此外,地址单元还提供了并行操作地址寄存器的功能,从而节省了更新地址寄存器的时间;
  • 向量寄存器组 (Vector Registers): 包含 8 个 128-bit 的向量寄存器 (QR)。每个寄存器可以表示为 16 x 8-bit、8 x 16-bit 或 4 x 32-bit 的数据向量;
  • QACC 累加寄存器: QACC 累加寄存器可用于 8-bit 或 16-bit 数据的乘累加运算。对于 ESP32-S3 而言,QACC 由 160-bit 的 QACC_H 与 160-bit 的 QACC_L 构成;对于 ESP32-P4 而言,QACC_H 与 QACC_L 的大小各为 256-bit。此外,可以将内存中的数据加载到 QACC 中,也可以将初始值重置为 0;
  • ACCX 累加寄存器: ACCX 是一个 40-bit 寄存器,其存储的数据既可以是 8-bit 数据的乘累加结果,也可以是 16-bit 数据的乘累加结果,取决于使用的指令。 

如果您对上述 PIE 架构还不熟悉,无需担心。本文将从实用角度出发,以直观的方式展示 PIE 的应用场景和性能表现。 

基本的指令格式与应用 

如果您的工作经常涉及 AI 模型推理或信号处理,您可能会经常遇到内存拷贝与向量计算等应用场景。以内存拷贝和向量加法为例,您可以通过内联汇编或 `.s` 文件来使用 PIE 指令。需要注意的是,PIE 中的大多数指令都可以在一个周期内从 128-bit Q 寄存器中加载或存储数据,因此,数据应 128-bit 对齐。 

内存拷贝加速 

在内存拷贝场景中,PIE 中的 8 个 128 位 Q 寄存器可用于读取和存储数据,从而实现内存拷贝加速。ESP32-P4 的 PIE 格式如下:

esp.vld.128.ip qu,rs1,imm  # 从内存中加载 128-bit 数据 ; 该指令将 128-bit 的数据从内存加载到寄存器 qu 中,同时指针按立即数 (imm) 进行递增。 
; imm 的取值范围为 -2048 到 2032,步长为 16。 esp.vst.128.ip qu,rs1,imm  # 将 128-bit 数据写入到内存中 ; 该指令将寄存器 qu 中的 128 位数据存储到内存中,同时指针按立即数 (imm) 进行递增。 
; imm 的取值范围为 -2048 到 2032,步长为 16。

接下来,根据上述指令,以 `.s` 文件 的形式编写用于内存复制的代码。

.data .align 16 .text .align 4 .global memcpy_pie .type   memcpy_pie, @function 
memcpy_pie: # a0: store_ptr  # a1: load_ptr # a2: length(bytes) li x28,0 Loop: esp.vld.128.ip q0, a1, 16 esp.vld.128.ip q1, a1, 16 esp.vld.128.ip q2, a1, 16 esp.vld.128.ip q3, a1, 16 esp.vld.128.ip q4, a1, 16 esp.vld.128.ip q5, a1, 16 esp.vld.128.ip q6, a1, 16 esp.vld.128.ip q7, a1, 16 esp.vst.128.ip q0, a0, 16 esp.vst.128.ip q1, a0, 16 esp.vst.128.ip q2, a0, 16 esp.vst.128.ip q3, a0, 16 esp.vst.128.ip q4, a0, 16 esp.vst.128.ip q5, a0, 16 esp.vst.128.ip q6, a0, 16 esp.vst.128.ip q7, a0, 16 addi x28, x28, 128 bge x28, a2, exit j Loop exit: ret 

在上述汇编文件中,原始数据分别存储在寄存器 q0 至 q7 中,并回写到指定的内存块。

 

本文在 ESP32-P4 上进行了 `memcpy` 对比实验。ESP32-P4 的运行频率为 360 MHz,二级缓存大小为 128 KB,二级缓存行大小为 64 Bytes。测试结果显示,在重复 100 轮复制 2040 个字节的过程中,PIE 相较于标准库快 74.3%,相较于采用单字节拷贝的 ANSI C 版本快 97.2%。 

此外,深入探索内存拷贝速度差异的原因或许能给您带来更多启发。 

Newlib-esp32 包含了各个平台的 `memcpy` 实现方法。以基于 RISC-V 的 ESP32-P4 为例,与单字节拷贝相比,优化后的 `memcpy` 通过使用内存对齐和块级传输提高了数据的拷贝效率。同时,PIE 通过使用 8 个 128-bit 的寄存器来加载和存储数据,进一步加快了内存拷贝的速度。 

void * 
__inhibit_loop_to_libcall 
memcpy(void *__restrict aa, const void *__restrict bb, size_t n) 
{ #define BODY(a, b, t) { \ t tt = *b; \ a++, b++; \ *(a - 1) = tt; \ } char *a = (char *)aa; const char *b = (const char *)bb; char *end = a + n; uintptr_t msk = sizeof (long) - 1; if (unlikely ((((uintptr_t)a & msk) != ((uintptr_t)b & msk)) || n < sizeof (long))) { 
small: if (__builtin_expect (a < end, 1)) while (a < end) BODY (a, b, char); return aa; } if (unlikely (((uintptr_t)a & msk) != 0)) while ((uintptr_t)a & msk) BODY (a, b, char); long *la = (long *)a; const long *lb = (const long *)b; long *lend = (long *)((uintptr_t)end & ~msk); if (unlikely (lend - la > 8)) { while (lend - la > 8) { long b0 = *lb++; long b1 = *lb++; long b2 = *lb++; long b3 = *lb++; long b4 = *lb++; long b5 = *lb++; long b6 = *lb++; long b7 = *lb++; long b8 = *lb++; *la++ = b0; *la++ = b1; *la++ = b2; *la++ = b3; *la++ = b4; *la++ = b5; *la++ = b6; *la++ = b7; *la++ = b8; } } while (la < lend) BODY (la, lb, long); a = (char *)la; b = (const char *)lb; if (unlikely (a < end)) goto small; return aa; 
} 

数学运算加速 

以 `int16_t` 类型的向量加法为例,相较于内存拷贝而言,其增加了一条加法指令。ESP32-P4 上的指令格式如下: 

esp.vadd.s16 qv, qx, qy  ; 该指令对寄存器 qx 和 qy 中的 16 位数据执行向量有符号加法。 
; 然后,对计算得到的 8 个结果进行饱和处理,并将饱和后的结果写入寄存器 qv。

接下来,本文将以内联汇编方式编写 PIE 代码: 

void add_ansic(int16_t *x, int16_t *y, int16_t *z, int n) 
{ for (int i = 0; i < n; i++) { z[i] = x[i] + y[i]; } 
} void add_pie(int16_t *x, int16_t *y, int16_t *z, int n) 
{ asm volatile( " addi sp, sp, -32 \n" " sw x31, 28(sp) \n" " sw x30, 24(sp) \n" " sw x29, 20(sp) \n" " sw x28, 16(sp) \n" " sw x27, 12(sp) \n" " mv x31, %0 \n" " mv x30, %1 \n" " mv x29, %2 \n" " mv x28, %3 \n" "li x27, 0 \n" "loop:\n" " beq x27, x28, exit \n" " esp.vld.128.ip q0, x31, 16 \n" " esp.vld.128.ip q1, x31, 16 \n" " esp.vld.128.ip q2, x31, 16 \n" " esp.vld.128.ip q3, x31, 16 \n" " esp.vld.128.ip q4, x30, 16 \n" " esp.vld.128.ip q5, x30, 16 \n" " esp.vld.128.ip q6, x30, 16 \n" " esp.vld.128.ip q7, x30, 16 \n" " esp.vadd.s16 q0, q0, q4 \n" " esp.vadd.s16 q1, q1, q5 \n" " esp.vadd.s16 q2, q2, q6 \n" " esp.vadd.s16 q3, q3, q7 \n" " esp.vst.128.ip q0, x29, 16 \n" " esp.vst.128.ip q1, x29, 16 \n" " esp.vst.128.ip q2, x29, 16 \n" " esp.vst.128.ip q3, x29, 16 \n" " addi x27, x27, 32 \n" " j loop \n" "exit:\n" " lw x31, 28(sp) \n" " lw x30, 24(sp) \n" " lw x29, 20(sp) \n" " lw x28, 16(sp) \n" " lw x27, 12(sp) \n" " addi sp, sp, 32 \n" :: "r" (x), "r" (y) , "r" (z), "r" (n)     ); 
} 

随后,在与内存拷贝实验相同的条件下,进行了 100 轮 `int16_t` 的向量加法实验,每个向量的长度为 2048。测试结果显示,PIE 版本相比 ANSI C 版本的速度提升了 93.8%。 

综上所述,本文介绍了 PIE 的两个应用场景及其实现方法。此外,PIE 还包含其他指令,您可以参考上述流程进行测试。 

添加 PIE 相关组件到工程中 

如果您不想编写 PIE 指令,但仍想加速 AI 推理或信号处理,您可以尝试使用集成了 PIE 指令的组件来简化开发过程。以下是一些可以轻松集成到您的现有项目中,以加速 AI 和 DSP 性能的乐鑫官方组件: 

  • esp-tflite-micro: 在 `esp-tflite-micro` 中的 esp-nn 组件使用 PIE 优化了一些 AI 算子,从而加速了模型的推理时间;
  • esp-dl: esp-dl 提供了一种专为 ESP 系列芯片设计的轻量级、高效的神经网络推理框架,能够高效实现诸如 Conv2D、Pool2D、Gemm、Add 和 Mul 等常见的 AI 算子;
  • esp-dsp: esp-dsp 通过汇编优化实现矩阵乘法、点积以及 FFT 等数学运算,同时也提供了 ANSI-C 实现版本。

总结 

总而言之,PIE 包含如下特性: 

  • 支持 128-bit 位宽的向量数据操作,包括:乘法、加法、减法、累加、移位、比较等; 
  • 合并数据搬运指令与运算指令; 
  • 支持非对齐 128-bit 带宽的向量数据; 
  • 支持取饱和操作。 

借助 PIE 指令或相关组件,您可以尝试加速现有项目的计算过程。 

欢迎您按照本文步骤进行尝试并分享您的经验! 

关键字:手机建站服务_自己可以做微信公众号吗_seo模板建站_网络营销推广微信hyhyk1效果好

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: