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)
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.
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:
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:
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.