F29H850TU: Why not parallel excution?

Part Number: F29H850TU

Hi Experts,

My customer is optimizing their code and they find that somes the instruction are not paralleled. 

For example, in the below instructionL

0x20106790    4050              LD.32   M2,*(ADDR2)A4
    0x20106792    35c3 0044         LD.32   M3,*(ADDR1)(A4+#0x4)
    0x20106796    5493              SSUBF   M2,M2,M3
    0x20106798    4091              LD.32   M4,*(ADDR2)A5
    0x2010679A    5c94              SMPYF   M2,M2,M4
    0x2010679C    b5c3 5402 5402    LD.32   M3,*(ADDR1)(A4+#0x8)
                               || SSUBF   M0,M0,M2

 

The First and second LD.32 seemly have no address conflicts, but they are out paralleled, or combined into a LD.64.

Also, the second LD.32 does not parallel with the SSUBF intruction to its next, like the last two intruction did.

Why they are not paralleled? What is the bottle neck in this example?

To extend to question a bit more, how can we understand what is the bottle neck that cuase a non-paralleld instrucitons?

Regards,

Hang

  • Short answer

    In this snippet the limiter is the data-dependency chain, not packet size or load-port capacity.

    LD.32  M2, *(ADDR2)A4            ─┐
    LD.32  M3, *(ADDR1)(A4+#0x4)     ─┤  M2, M3 are load results
    SSUBF  M2, M2, M3                ←─┘  consumes both loads
    LD.32  M4, *(ADDR2)A5            ─┐
    SMPYF  M2, M2, M4                ←─┘  consumes SSUBF result + M4
    LD.32  M3, *(ADDR1)(A4+#0x8)     ─┐  independent destination
    || SSUBF M0, M0, M2              ←─┘  consumes SMPYF result (already produced)
    

    Every pair that failed to pack has a producer→consumer relationship on an M register. The one pair that did pack (LD.32 M3 || SSUBF M0,M0,M2) writes different destinations and reads nothing the partner produces. That is the pattern to look for first — instructions in a packet all issue in the same cycle, so a result cannot be consumed in the packet that produces it.

    Packet size is not the constraint here: a packet may mix 16-, 32-, and 48-bit instructions up to 128 bits total 1, and the two 16-/32-bit loads would fit easily.

    On the two leading LD.32s specifically

    Two loads plus one store per packet is legal on C29 2, and reading A4 twice in a packet is also legal — an Ax register may be read multiple times but written only once per packet 2.

    Knowledge gap: the retrieved documentation does not state why the compiler left these two loads unpacked, nor why they were not merged into a single LD.64 M2:M3. Candidate causes (memory-port/bank conflict between the two accesses, or the compiler being unable to prove 64-bit alignment of A4 for an LD.64 merge) are not confirmed by the evidence retrieved here — I will not assert either. If this matters for the optimization effort, this is worth escalating with the compiler version, optimization flags, and the C source so the code-generation decision can be reproduced.

    General checklist: what blocks packing

    Work through these in order when a packet looks under-filled:

    Constraint Rule
    Data dependency Producer and consumer cannot share a packet (the dominant cause above)
    Packet size Total encoding ≤ 128 bits 1
    Memory ops ≤ 2 loads + 1 store per packet 2
    Register writes Only one write per Ax register; the assembler flags two instructions writing the same destination 2
    Functional units 8-way issue is an upper bound, not a guarantee for any instruction mix 3; FP MAC throughput is two per cycle (one integer MAC) 4
    Special instructions IDLE cannot be packetized, ECCSELFTEST must stand alone, PRESERVE packs only with protected call/branch/return 1
    Delay slots Discontinuity instructions cannot sit in delay slots; RPC, EMUSTOP0, XC/XCP have further restrictions 1

    For this loop, the actionable lever is breaking the serial M2 chain — e.g., software-pipelining or unrolling so independent iterations supply work to fill the packets, rather than expecting the scheduler to pack a strictly sequential load→subtract→multiply chain.

    Follow up: Would you like help interpreting the compiler's scheduling decisions directly — e.g., what --opt_level/assembly-listing options expose per-packet issue reasons for this loop?


    1. C29x CPU and Instruction Set Reference Guide (SPRUIY2A)
    2. C29x CPU and Instruction Set Reference Guide (SPRUIY2A), p.52
    3. F29H85x Technical Reference Manual (SPRUJ79C), p.134
    4. E2E: F29H850TU — Complete a MAC operation in one clock cycle