開発
#data
esp32-s3-pie-simd-optimization
ESP32-S3 Processor Instruction Extensions (PIE) SIMD reference for accelerating C code. Use when converting scalar C loops into PIE SIMD assembly (EE.* instructions). Covers 128-bit QR registers, vector arithmetic, MAC, non-aligned data, FFT, and common patterns. Target chip: ESP32-S3 (Xtensa LX7 with TIE extensions).
DeepseekModel
キュレーション済みスキル
品質 優秀 · 90
v1.0.0
取得
https://deepseekmodel.com/api/download.php?id=espressif-esp-dl-tools-agents-skills-esp32s3-pie-simd-skill-md&format=skill
ダウンロード .skill
標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能
.skill ファイルの system_prompt フィールドの実際の内容。
name ESP32-S3 PIE SIMD Optimization description ESP32-S3 Processor Instruction Extensions (PIE) SIMD reference for accelerating C code. Use when converting scalar C loops into PIE SIMD assembly (EE.* instructions). Covers 128-bit QR registers, vector arithmetic, MAC, non-aligned data, FFT, and common patterns. Target chip: ESP32-S3 (Xtensa LX7 with TIE extensions). ESP32-S3 PIE SIMD Quick Reference REGISTERS General Purpose Register Count Width Use AR (a0-a15) 16 32-bit Address/data, a1=sp, a2-a7=args, a8-a15=addr operands QR (q0-q7) 8 128-bit SIMD vectors: 16×8-bit, 8×16-bit, or 4×32-bit lanes FR (f0-f15) 16 32-bit IEEE754 float Special Registers (PIE-specific) Register Width Access via Purpose SAR 6-bit RSR/WUR.SAR Mul result right-shift amount (bits) SAR_BYTE 4-bit RUR/WUR.SAR_BYTE Byte shift amount for SRC.Q ACCX 40-bit RUR/WUR ACCX_0,ACCX_1 Scalar accumulator (sum of all lane products) QACC_H 160-bit RUR/WUR QACC_H_0..4 Per-lane accumulator high (8×20-bit or 4×40-bit) QACC_L 160-bit RUR/WUR QACC_L_0..4 Per-lane accumulator low FFT_BIT_WIDTH 4-bit WUR.FFT_BIT_WIDTH Bit-reversal width (0→3bit ... 7→10bit) UA_STATE 128-bit RUR/WUR UA_STATE Unaligned load persistent state Special Register Access WSR.SAR aN ; write SAR RSR.SAR aN ; read SAR XSR.SAR aN ; exchange AR and SAR WUR.ACCX_0 aN ; write ACCX[31:0] WUR.ACCX_1 aN ; write ACCX[39:32] (lower 8 bits of aN used) RUR.ACCX_0 aN ; read ACCX[31:0] RUR.ACCX_1 aN ; read ACCX[39:32] → aN[7:0] WUR.SAR_BYTE aN ; write SAR_BYTE RUR.SAR_BYTE aN ; read SAR_BYTE WUR.QACC_H_0 aN ; write QACC_H segment 0 (bits 31:0) RUR.QACC_H_0 aN ; read QACC_H segment 0 (bits 31:0) ; QACC_H segments: _0(31:0) _1(63:32) _2(95:64) _3(127:96) _4(159:128) ; QACC_L same segment layout EE.ZERO.ACCX ; ACCX = 0 EE.ZERO.QACC ; QACC_H = 0, QACC_L = 0 EE.ZERO.Q qN ; qN = 0 ALIGNMENT RULES (CRITICAL) PIE loads/stores force address low bits to 0: 128-bit access: low 4 bits forced to 0 (16-byte aligned) 64-bit access: low 3 bits forced to 0 (8-byte aligned) 32-bit access: low 2 bits forced to 0 (4-byte aligned) 16-bit access: low 1 bit forced to 0 (2-byte aligned) Always declare buffers with __attribute__((aligned(16))) or use heap_caps_aligned_alloc(16, size, MALLOC_CAP_DEFAULT) . Unaligned Load Pattern (3 instructions) EE.LD.128.USAR.IP q0, aN, 16 ; load aligned chunk, save offset→SAR_BYTE, aN+=16 EE.VLD.128.IP q1, aN, 16 ; load next aligned chunk, aN+=16 EE.SRC.Q q2, q0, q1 ; {q1,q0} >> SAR_BYTE*8 → q2 (lower 128 bits) INSTRUCTION CLASSIFICATION BY OPERATION 1. LOAD (Memory → QR / QACC) EE.VLD.128.IP qu, as, imm16 ; qu=load128(aligned(as)), as+=sext(imm16)*16 EE.VLD.128.XP qu, as, ad ; qu=load128(aligned(as)), as+=ad EE.LD.128.USAR.IP qu, as, imm16 ; SAR_BYTE=as[3:0], qu=load128(aligned(as)), as+=sext(imm16)*16 EE.LD.128.USAR.XP qu, as, ad ; SAR_BYTE=as[3:0], qu=load128(aligned(as)), as+=ad EE.VLD.H.64.IP qu, as, imm8 ; qu[127:64]=load64(aligned(as)), as+=sext(imm8)*8 EE.VLD.L.64.IP qu, as, imm8 ; qu[63:0]=load64(aligned(as)), as+=sext(imm8)*8 EE.VLDBC.8 qu, as ; qu = broadcast(load8(as)), as += 1 EE.VLDBC.8.IP qu, as, imm1 ; qu = broadcast(load8(as)), as += imm1 (0..1) EE.VLDBC.16 qu, as ; qu = broadcast(load16(aligned(as))), as += 2 EE.VLDBC.32 qu, as ; qu = broadcast(load32(aligned(as))), as += 4 EE.LDQA.S8.128.IP as, imm16 ; sign-extend 16×8bit→16×20bit into QACC_H+L, as+=sext(imm16)*16 EE.LDQA.S16.128.IP as, imm16 ; sign-extend 8×16bit→8×40bit into QACC_H+L, as+=sext(imm16)*16 EE.LDQA.U8.128.IP as, imm16 ; zero-extend 16×8bit→16×20bit into QACC_H+L, as+=sext(imm16)*16 EE.LDQA.U16.128.IP as, imm16 ; zero-extend 8×16bit→8×40bit into QACC_H+L, as+=sext(imm16)*16 ; IP = Immediate Post-increment, XP = register post-increment ; VLD.128.IP: step = sext(imm16)*16, range -512..496 (6-bit immediate) ; VST.128.IP: step = sext(imm8)*16, range -2048..2032 (8-bit immediate) ; VLD.H/L.64.IP: step = sext(imm8)*8, range -1024..1016 2. STORE (QR → Memory) EE.VST.128.IP qv, as, imm16 ; store128(qv, aligned(as)), as+=sext(imm8)*16 EE.VST.128.XP qv, as, ad ; store128(qv, aligned(as)), as+=ad EE.VST.H.64.IP qv, as, imm8 ; store64(qv[127:64], aligned(as)), as+=sext(imm8)*8 EE.VST.L.64.IP qv, as, imm8 ; store64(qv[63:0], aligned(as)), as+=sext(imm8)*8 3. VECTOR ARITHMETIC (lane-wise, saturated) EE.VADDS.S8 qa, qx, qy ; qa[i]=saturate_s8(qx[i]+qy[i]) for i in 0..15 EE.VADDS.S16 qa, qx, qy ; qa[i]=saturate_s16(qx[i]+qy[i]) for i in 0..7 EE.VADDS.S32 qa, qx, qy ; qa[i]=saturate_s32(qx[i]+qy[i]) for i in 0..3 EE.VSUBS.S8 qa, qx, qy ; qa[i]=saturate_s8(qx[i]-qy[i]) EE.VSUBS.S16 qa, qx, qy ; qa[i]=saturate_s16(qx[i]-qy[i]) EE.VSUBS.S32 qa, qx, qy ; qa[i]=saturate_s32(qx[i]-qy[i]) ; Combined Load+Arithmetic (qu=load result, qa=arithmetic result) EE.VADDS.S8.LD.INCP qu, as, qa, qx, qy ; as+=16 EE.VADDS.S16.LD.INCP qu, as, qa, qx, qy ; as+=16 EE.VADDS.S32.LD.INCP qu, as, qa, qx, qy ; as+=16 ; Combined Store+Arithmetic (store qv, compute qa) EE.VADDS.S8.ST.INCP qv, as, qa, qx, qy ; store qv→aligned(as), as+=16 4. VECTOR MULTIPLY (lane-wise, SAR right-shift) EE.VMUL.S8 qz, qx, qy ; qz[i]=(s8*qx[i] * s8*qy[i]) >> SAR[5:0] for i=0..15 EE.VMUL.S16 qz, qx, qy ; qz[i]=(s16*qx[i] * s16*qy[i]) >> SAR[5:0] for i=0..7 EE.VMUL.U8 qz, qx, qy ; unsigned variant EE.VMUL.U16 qz, qx, qy ; unsigned variant ; SET SAR BEFORE MULTIPLY: ; movi aN, shift_amount ; wsr.sar aN 5. COMPLEX MULTIPLY (16-bit, 4 complex pairs × selected qy half) EE.CMUL.S16 qz, qx, qy, sel4 ; sel4 selects one 32-bit complex number from qy: ; temp[31:0] = qy[sel4*32+31:sel4*32] ; For each of the 4 complex pairs in qx (i=0..3): ; qz[64*i+15:64*i] = qx[64*i+15:64*i] * temp[15:0] - qx[64*i+31:64*i+16] * temp[31:16] ; qz[64*i+31:64*i+16] = qx[64*i+15:64*i] * temp[31:16] + qx[64*i+31:64*i+16] * temp[15:0] ; All results right-shifted by SAR. All 4 complex pairs multiply with the ; same selected temp value (not pairwise with corresponding qy elements). 6. MULTIPLY-ACCUMULATE ACCX mode (scalar sum of all lane products): EE.VMULAS.S8.ACCX qx, qy ; ACCX += Σ(qx[i] * qy[i]) for i=0..15, saturated to 40-bit EE.VMULAS.S16.ACCX qx, qy ; ACCX += Σ(qx[i] * qy[i]) for i=0..7 EE.VMULAS.U8.ACCX qx, qy ; unsigned EE.VMULAS.U16.ACCX qx, qy ; unsigned ; Read raw result: RUR.ACCX_0 aN (low 32), RUR.ACCX_1 aN (high 8) EE.SRS.ACCX rd, rs, 0 ; arithmetic right shift ACCX by rs[5:0], write back to ACCX ; and write saturated 32-bit signed result to rd ; rd = min(max(ACCX>>rs[5:0], -2^31), 2^31-1) QACC mode (per-lane accumulation, 20-bit or 40-bit per lane): EE.VMULAS.S8.QACC qx, qy ; QACC[i] += qx[i]*qy[i], 20-bit signed saturated per lane EE.VMULAS.S16.QACC qx, qy ; QACC[i] += qx[i]*qy[i], 40-bit signed saturated per lane EE.VMULAS.U8.QACC qx, qy ; unsigned EE.VMULAS.U16.QACC qx, qy ; unsigned ; Fused MAC + 128-bit load (same as P4 ESP.VMULAS.*.QACC.LD.XP): ; QACC += qx * qy, then qu = load128(aligned(as)), as += ad EE.VMULAS.S8.QACC.LD.XP qu, as, ad, qx, qy EE.VMULAS.S16.QACC.LD.XP qu, as, ad, qx, qy EE.VMULAS.U8.QACC.LD.XP qu, as, ad, qx, qy EE.VMULAS.U16.QACC.LD.XP qu, as, ad, qx, qy ; Also .LD.IP with immediate post-increment (as += imm, typically 16) EE.VMULAS.S8.QACC.LD.IP qu, as, imm, qx, qy EE.VMULAS.S16.QACC.LD.IP qu, as, imm, qx, qy ; Extract QACC→QR with right-shift+sat (shift amount from as register, NOT SAR): EE.SRCMB.S8.QACC qu, as, 0 ; 16×20-bit→16×8-bit, R-shift by as[4:0], saturate to s8→qu EE.SRCMB.S16.QACC qu, as, 0 ; 8×40-bit→8×16-bit, R-shift by as[5:0], saturate to s16→qu ; QACC values are also updated with the shifted results (read-modify-write) 7. COMPARISON (result = 0xFF on true, 0 on false) EE.VMAX.S8 / S16 / S32 qa, qx, qy ; qa[i] = max(qx[i], qy[i]) EE.VMIN.S8 / S16 / S32 qa, qx, qy ; qa[i] = min(qx[i], qy[i]) EE.VCMP.EQ.S8 qa, qx, qy ; qa[i] = (qx[i]==qy[i]) ? 0xFF : 0 EE.VCMP.LT.S8 qa, qx, qy ; qa[i] = (qx[i] < qy[i]) ? 0xFF : 0 EE.VCMP.GT.S8 qa, qx, qy ; qa[i] = (qx[i] > qy[i]) ? 0xFF : 0 ; Use ANDQ with mask to implement conditional selection (e.g. ReLU) 8. BITWISE EE.ANDQ qa, qx, qy ; qa = qx & qy (128-bit) EE.ORQ qa, qx, qy ; qa = qx | qy EE.XORQ qa, qx, qy ; qa = qx ^ qy EE.NOTQ qa, qx ; qa = ~qx 9. SHIFT EE.VSL.32 qa, qs ; qa[i] = qs[i] << SAR[5:0] (4×32-bit logical left) EE.VSR.32 qa, qs ; qa[i] = qs[i] >> SAR[5:0] (4×32-bit arithmetic right) EE.SRC.Q qa, qs0, qs1 ; qa = ({qs1,qs0} >> SAR_BYTE*8)[127:0] ; SRC.Q used with LD.128.USAR for unaligned access 10. DATA MOVEMENT MV.QR qu, qs ; qu = qs EE.ZERO.Q qa ; qa = 0 EE.MOVI.32.A qs, au, sel4 ; au = qs[sel4*32+31:sel4*32] (extract 32-bit lane) EE.MOVI.32.Q qu, as, sel4 ; qu[sel4*32+31:sel4*32] = as (insert 32-bit lane) EE.MOV.S8.QACC qs ; sign-extend 16×8bit→16×20bit to QACC_H+L EE.MOV.S16.QACC qs ; sign-extend 8×16bit→8×40bit to QACC_H+L EE.MOV.U8.QACC qs ; zero-extend 16×8bit→16×20bit to QACC_H+L EE.MOV.U16.QACC qs ; zero-extend 8×16bit→8×40bit to QACC_H+L 11. ACTIVATION
このスキルを起動するキーワード。クリックでコピーできます。
このスキルにはトリガーワードがありません。
ダウンロードした .skill に含まれるフィールド。
| フィールド | 説明 |
|---|---|
| format | フォーマット識別子(skill/v1) |
| skill_id | スキル固有 ID |
| name | スキル名 |
| version | バージョン |
| description | 説明 |
| category | カテゴリ(配列) |
| trigger_words | トリガーワード |
| tags | タグ |
| source | ソース |
| source_url | ソース URL(本ページ) |
| exported_at | エクスポート日時(ダウンロード毎) |
| system_prompt | システムプロンプト本文 |
| model_config | モデル設定:provider / model / temperature / max_tokens / top_p |
| examples | サンプル |
| install_guide | 各プラットフォームの導入説明(Coze / Dify / Claude / カスタム) |