Shop OBEX P1 Docs P2 Docs Learn Events
flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler - Page 129 — Parallax Forums

flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler

1123124125126127129»

Comments

  • Next problem: How do I properly declare shared memory used by multiple cogs as volatile so that the compiler does not optimize away consecutive reads?

    Example:

    struct __using("Sano_trafo.spin2") asm;
    static volatile TrafoCtrlDescr ctrl;
    static int ccog;
    ...
       ccog= _coginit (ANY_COG, asm.GetStartAdr (), &ctrl);
        _waitms (1);
        _wrpin (pinTrI, P_ADC | P_ADC_GIO);
        _waitx (TRAFO_PERIOD * 100);
        int32_t lo= ctrl.currI;
        _wrpin (pinTrI, P_ADC | P_ADC_VIO);
        _waitx (TRAFO_PERIOD * 100);
        _waitms (1);
        int32_t hi= ctrl.currI;
        _cogstop (ccog);
        _wrpin (pinTrI, P_ADC | P_ADC_1X);
        int32_t gain= round (0x4000 * TRAFO_SCALE_I / (hi - lo));
        asm.SetOffset (lo);
        asm.SetGain (gain);
    

    This works as it's supposed to. But as soon as I ommit the second _waitms() the compiler thinks he's smart and that the two accesses to ctrl.currI must have the same value so that hi and lo are the same and can be optimized into a single variable. The compiled code is:

        mov arg01, #1
        call    #__system___waitms ' first _waitms()
        wrpin   ##1048624, #8
        waitx   ##400000 ' first _waitx()
        add ptr__dat__, ##74320
        rdlong  local01, ptr__dat__ ' first read of ctrl.currI
        wrpin   ##1081392, #8
        waitx   ##400000 ' second _waitx()
        add ptr__dat__, #40
        rdlong  arg01, ptr__dat__ ' read of ccog
        sub ptr__dat__, ##74360 ' second read of ctrl.currI is optimized away!
        cogstop arg01
        mov arg02, ##1146928
        wrpin   ##1146928, #8
        mov arg01, local01 ' should be hi-lo
        sub arg01, local01 ' but compiles to lo-lo !
    

    The call to _waitms() seems to act as some sort of "clear optimization cache" command. Same for printf() and the like. This makes debugging very unpredictable. As soon as I remove the debug output the behaviour of the program changes. :# I'm almost sure this is my fault. But it would be really helpful if I knew how to avoid that.
    (@ersmith I can send you the complete project if you need it)

  • This read elimination is blocked by most function calls, other memory writes and certain other instructions.

    We should add an explicit memory fence intrinsic though.

  • I thought volatile is exactly meant for that purpose. But currently, it has no effect at all. I wonder how all my other programs work at all. Things like mailboxes used by at least two cogs are very common with the Propeller. There should be a safe way to implement them without guessing about the optimisations.

  • Yeah volatile is ignored by the frontend because ???

    Spin doesn't have an equivalent annotation, so ??? there.

    Branch instructions stop the optimization even if it could otherwise happen, so thongs like wait loops always act as a fence.

    There's also a flag to disable these memory optimizations outright, but idk what its called and am phoneposting from a train rn.

Sign In or Register to comment.