• AVR Freaks

Hot!How to implemet fractcomplex multiply operation

Author
Maple
PIC-fan
  • Total Posts : 44
  • Reward points : 0
  • Joined: 2016/03/06 21:42:36
  • Location: China
  • Status: offline
2020/10/18 11:05:27 (permalink)
0

How to implemet fractcomplex multiply operation

Hello everyone! I wonder if anyone knows some "fast" fractcomplex-type multiplication routine.
I am using the belowing one, but I think it is not so optimized. Does anyone can share his idea on this...Thx!
BTW _Q15mpy, _Q15add, _Q15sub are functions from header "libq.h"
void FractCmplx_Mpy(fractcomplex* pX, fractcomplex* pY, fractcomplex* pZ)
{
 _Q15 q1, q2;
 
 q1 = _Q15mpy(pX->real, pY->real);
 q2 = _Q15mpy(pX->imag, pY->imag);
 pZ->real = _Q15sub(q1, q2);

 q1 = _Q15mpy(pX->imag, pY->real);
 q2 = _Q15mpy(pX->real, pY->imag);
 pZ->imag = _Q15add(q1, q2);
}

#1

8 Replies Related Threads

    du00000001
    Just Some Member
    • Total Posts : 3974
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: online
    Re: How to implemet fractcomplex multiply operation 2020/10/18 16:31:35 (permalink)
    0
    You "think it is not so optimized"?
    Why? Bacause it doesn't fit into your concept?
    Do you have any idea about the math behind that?

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #2
    Maple
    PIC-fan
    • Total Posts : 44
    • Reward points : 0
    • Joined: 2016/03/06 21:42:36
    • Location: China
    • Status: offline
    Re: How to implemet fractcomplex multiply operation 2020/10/18 20:02:05 (permalink)
    0
    du00000001
    You "think it is not so optimized"?
    Why? Bacause it doesn't fit into your concept?
    Do you have any idea about the math behind that?


    Yes, I think I may know sth. about it.
    It is my  routine "FractCmplx" which I think "not so optimized", not the _Q15xxx build-in functions.
    I read "16-Bit MCU and DSC Programmer’s Reference Manual" in chapter 4.15, there is a statement says :
    "In addition, four of the ten DSP  MAC  instructions are also capable of performing an operation with
    one  accumulator,  while  storing  out  the  rounded  contents  of  the  alternate  accumulator.  This
    feature  is  called  accumulator  Write-Back  (WB)  and  it  provides  flexibility  for  the  software
    developer. For instance, the Accumulator WB may be used to run two algorithms concurrently,
    or efficiently process complex numbers, among other things. I thought maybe my routine could use this advantage somehow, but I dont know how to implememt it and that the reason I posted this thread.
     
    BTW there is no _Q15mpy in <libq.h>, I wrote it by myself. the source code is belowing:
    _Q15 _Q15mpy(_Q15 x, _Q15 y)
    {
        volatile register int RegACC asm("A"); 
        RegACC = __builtin_clr();
        RegACC = __builtin_mpy(x, y, NULL, NULL, 0, NULL, NULL, 0); 
        return (__builtin_sac(RegACC, 0)); 
    }
     
     
    FractCmplx_Mpy
    #3
    1and0
    Access is Denied
    • Total Posts : 11320
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: How to implemet fractcomplex multiply operation 2020/10/18 22:09:07 (permalink)
    +1 (1)
    grchy
    It is my  routine "FractCmplx" which I think "not so optimized", not the _Q15xxx build-in functions.

    How optimized do you want? Your calling function within function is not going to help, neither will the Write-Back.

    Anyway, I think you overthinking this. Give this a try:
    void FractCmplx_Mpy(fractcomplex* pX, fractcomplex* pY, fractcomplex* pZ)
    {
        volatile register int result asm("A");
        
        result = __builtin_mpy(pX->real, pY->real, NULL, NULL, 0, NULL, NULL, 0);
        result = __builtin_msc(result, pX->imag, pY->imag, NULL, NULL, 0, NULL, NULL, 0, 0, 0);
        pZ->real = __builtin_sacr(result, 0);
        
        result = __builtin_mpy(pX->real, pY->imag, NULL, NULL, 0, NULL, NULL, 0);
        result = __builtin_mac(result, pX->imag, pY->real, NULL, NULL, 0, NULL, NULL, 0, 0, 0);
        pZ->imag = __builtin_sacr(result, 0);
    }

    which should take about ~30 instruction cycles.



    #4
    Maple
    PIC-fan
    • Total Posts : 44
    • Reward points : 0
    • Joined: 2016/03/06 21:42:36
    • Location: China
    • Status: offline
    Re: How to implemet fractcomplex multiply operation 2020/10/19 05:55:37 (permalink)
    0
    1and0
    grchy
    It is my  routine "FractCmplx" which I think "not so optimized", not the _Q15xxx build-in functions.

    How optimized do you want? Your calling function within function is not going to help, neither will the Write-Back.

    Anyway, I think you overthinking this. Give this a try:
    void FractCmplx_Mpy(fractcomplex* pX, fractcomplex* pY, fractcomplex* pZ)
    {
        volatile register int result asm("A");
        
        result = __builtin_mpy(pX->real, pY->real, NULL, NULL, 0, NULL, NULL, 0);
        result = __builtin_msc(result, pX->imag, pY->imag, NULL, NULL, 0, NULL, NULL, 0, 0, 0);
        pZ->real = __builtin_sacr(result, 0);
        
        result = __builtin_mpy(pX->real, pY->imag, NULL, NULL, 0, NULL, NULL, 0);
        result = __builtin_mac(result, pX->imag, pY->real, NULL, NULL, 0, NULL, NULL, 0, 0, 0);
        pZ->imag = __builtin_sacr(result, 0);
    }

    which should take about ~30 instruction cycles.







    Thx, 1and0! your way is better!
    but one question, is that correct without clear "accumulator"(40 bits long) before executing multiplication ?
    #5
    1and0
    Access is Denied
    • Total Posts : 11320
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: How to implemet fractcomplex multiply operation 2020/10/19 06:05:11 (permalink)
    0
    grchy
    Thx, 1and0! your way is better!

    You're welcome.
     

    but one question, is that correct without clear "accumulator"(40 bits long) before executing multiplication ?

    The result of the MPY is placed in the accumulator; i.e. Acc = real(X) * real(Y).
    #6
    Maple
    PIC-fan
    • Total Posts : 44
    • Reward points : 0
    • Joined: 2016/03/06 21:42:36
    • Location: China
    • Status: offline
    Re: How to implemet fractcomplex multiply operation 2020/10/19 06:29:16 (permalink)
    0
    Thx again 1and0! :)
    Maybe I didn't make my point clear, in my "_Q15mpy" routine:
    _Q15 _Q15mpy(_Q15 x, _Q15 y)
    {
        volatile register int RegACC asm("A"); 
        RegACC = __builtin_clr();  //line 1
        RegACC = __builtin_mpy(x, y, NULL, NULL, 0, NULL, NULL, 0); //line 2 
        return (__builtin_sac(RegACC, 0)); 
    }
     
    there is line 1 to clear the accumulator first, since accumulator is 40bit and x, y are both 16bit. if there is no line 1, maybe the result would go wrong?
    Actually, I didn't get your reply "The result of the MPY is placed in the accumulator; i.e. Acc = real(X) * real(Y)." so much... sorry
    #7
    1and0
    Access is Denied
    • Total Posts : 11320
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: How to implemet fractcomplex multiply operation 2020/10/19 06:55:12 (permalink)
    +1 (1)
    grchy
    Maybe I didn't make my point clear, in my "_Q15mpy" routine:
    _Q15 _Q15mpy(_Q15 x, _Q15 y)
    {
        volatile register int RegACC asm("A"); 
        RegACC = __builtin_clr();  //line 1
        RegACC = __builtin_mpy(x, y, NULL, NULL, 0, NULL, NULL, 0); //line 2 
        return (__builtin_sac(RegACC, 0)); 
    }
     
    there is line 1 to clear the accumulator first, since accumulator is 40bit and x, y are both 16bit. if there is no line 1, maybe the result would go wrong?
    Actually, I didn't get your reply "The result of the MPY is placed in the accumulator; i.e. Acc = real(X) * real(Y)." so much... sorry

    There is NO need to clear the accumulator first, because the result of the multiplication is placed into the entire accumulator; that is, Acc = x * y.  16-bit x multiplies 16-bit y gives a product of 32-bit which is then sign-extended to 40 bits and put inside the accumulator. Hope this is clear. ;)
    #8
    Maple
    PIC-fan
    • Total Posts : 44
    • Reward points : 0
    • Joined: 2016/03/06 21:42:36
    • Location: China
    • Status: offline
    Re: How to implemet fractcomplex multiply operation 2020/10/19 07:01:12 (permalink)
    0
    Aye, Aye! Master, pretty clear this time! thank you sooooo much! :)
    #9
    Jump to:
    © 2020 APG vNext Commercial Version 4.5