This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADDSP/ADDDP instructions in a a SPLOOP (DM4148 C674x DSP)

I'm developing an assembler code with SPLOOP instruction.

It's a simple counter cycle with integer value and with float.

The inputs are:

A12 = 0x0000001 

A4 = 0x3F800000 (1.0 float)

B6 = 2047

the main code is:

ZERO .L1 A30
ZERO .L2 B25

MVC .S2 B6, ILC
NOP 4
;-----------------------------------
SPLOOP 1

ADDSP .L2X B25, A4, B25
|| ADD .L1 A30, A12, A30

SPKERNEL 0,0 ; End loop
;-----------------------------------

The results are:

B25 = 0x44000000 (512.0 float)
A30 = 0x000007FF (2047)

The A30 is correct but the B25 it's wrong (I expected a value of 2047.0 float).

Why? What's wrong?

Thank you.

  • I don't know the full answer, but I can shed some light.

    ADDSP is not a single cycle instruction.  And there are some pipeline hazards associated with it.

    Rather than learning all the details, I suggest you program this in linear assembly, or even C.  Then let the compiler handle the details for you.  Learn about linear assembly in the C6000 compiler manual chapter titled Using the Assembly Optimizer.

    Thanks and regards,

    -George

  • Thank you.

    I'm trying to implement a FIR filter with instructions MPYSP and ADDSP in a loop made with the SPLOOP ii istruction.

    How can I calculate the ii value knowing the instructions used in the loop?

    This is my loop implementation but I have determined the value ii by trial.

    SPLOOP 6 

    MPYSP .M2 B_state, A_b, B_mpysp               ; B_mpy = b(0)*x(n)
    LDW .D1 *A_fir_coeff++, A_b                   ; R_b = b(1) ; fir_coeff->b(2)
    LDW .D2 *B_fir_states++, B_state              ; sample = x(n-1) ; fir_states->x(n-2)

    NOP
    NOP

    ADDSP .L2 B_sumsp, B_mpysp, B_sumsp           ; B_sum = b(0)*x(n) + b(1)*x(n-1) + ... + b(N-2)*x(n-(N-2))

    SPKERNEL 6,0 

  • Please see the chapter of the C674x CPU manual titled Software Pipelined Loop (SPLOOP) Buffer.

    Thanks and regards,

    -George

  • ii is about algorithm rather then any given mix of instructions. Therefore there is no general rule. But one can say this. If you manage to arrange instructions in such manner that ii is equal to critical path, then performance would be optimal. In presented case critical path is latency of ADDSP instruction, because its result is used as input for next ADDSP. Therefore sequence with minimum possible ii would have to look something like this:

    SPLOOP 4
    LDW||LDW
    NOP 4
    MPYSP
    NOP 3
    ADDSP
    SPKERNEL x,y
    

    So that ADDSP is executed every 4th cycle and actually accumulates the result. However! If inputs are long enough, then you should ask yourself what prevents you from using multiple accumulators and add them together afterwards. In other words

    SPLOOP 4
    LDW||LDW
    LDW||LDW
    LDW||LDW
    LDW||LDW
    NOP
    MPYSP
    MPYSP
    MPYSP
    MPYSP
    ADDSP
    ADDSP
    ADDSP
    ADDSP
    SPRERNEL x,y

    where each ADDSP operates on own accumulator. So that "all of a sudden" performance is 4 times better. But is it best C647x can do? If inputs are long enough and are aligned at 8-byte boundary, then you can load double as much data per cycle, which might make following possible

    SPLOOP 4
    LDDW||LDDW
    LDDW||LDDW
    LDDW||LDDW
    LDDW||LDDW
    NOP
    MPYSP||MPYSP
    MPYSP||MPYSP
    MPYSP||MPYSP
    MPYSP||MPYSP
    ADDSP||ADDSP
    ADDSP||ADDSP
    ADDSP||ADDSP
    ADDSP||ADDSP
    SPKERNEL x,y

    which further doubles the performance. Disclaimer. "Might" in previous sentence means that I haven't thought it thoroughly enough to say that this is actually achievable. There might be some cross-path limitations that can force you to rearrange instruction sequence so that ii will have to be increased, but the idea is definitely worth considering. Even if ii has to be increased performance would still be better that 4-accumulator approach.

  • "Might" can be omitted. But question was also about ADDDP, and then counter-question is what is the context? If context is that input data is still single-precision and double-precision accumulator is required to meet precision goal, then one should recognize that 8 single-precision accumulators added together afterward do provide better accuracy than one. If accuracy is still not sufficient, then MPYSP2DP followed by ADDDP would be appropriate. But ADDDP has higher latency and can't be issued every cycle. So that loop would have follow below pattern:

    SPLOOP 6
    LDDW||LDDW
    NOP
    LDDW||LDDW
    NOP
    LDDW||LDDW
    MPYSP2DP||MPYSP2DP
    NOP
    MPYSP2DP||MPYSP2DP
    NOP
    MPYSP2DP||MPYSP2DP
    ADDDP||ADDDP
    NOP
    ADDDP||ADDDP
    NOP
    ADDDP||ADDDP
    SPKERNEL x,y
    

    which gives 1/2 performance of single precision. Even if input data is double-precision, it still should be possible to achieve same performance, because one can use NOPs in the start of the loop to sustain required data flow rate.

  • Andy Polyakov said:
    one should recognize that 8 single-precision accumulators added together afterward do provide better accuracy than one

    Not necessarily.  Depending on how you slice up the data to feed those 8 accumulators, you might have catastrophic cancellation that leads you farther from the correct answer than if you had done the strict serial semantics with just one accumulator.  On the other hand, splitting it into 8 could avoid catastrophic cancellation from the one accumulator method.

  • Archaeologist said:
    Andy Polyakov
    one should recognize that 8 single-precision accumulators added together afterward do provide better accuracy than one

    Not necessarily.  Depending on how you slice up the data to feed those 8 accumulators, you might have catastrophic cancellation that leads you farther from the correct answer than if you had done the strict serial semantics with just one accumulator.  On the other hand, splitting it into 8 could avoid catastrophic cancellation from the one accumulator method.

    Of course. I should have written "might" rather than "do". One can probably argue that "is likely to" is appropriate. One naturally has to consider accuracy vs. performance trade-offs, and in order to do that one has to know something about data and recognize available implementation options.