How does fcache work?
SRLM
Posts: 5,045
Exactly what the title says. I think I've run into a bug when using fcache and cmm together, and I'm trying to hunt it down. Basically, the bug only exists when both the -fcache and -mcmm flags are defined. I've run into this several times before, and IIRC it's always with loops. I've ignored it before by manually unrolling the loop, but I'm peeved enough now to try and hunt it down.
So, I would like to try and come up with a small program that reproduces the possible bug, but I don't know on what criteria a loop in CMM is put into fcache. Where can I find that sort of thing out?
ps: On my current code, this is the snippet that is causing problems:
It should end up coping one char array to another. It seems to loop the correct amount of times, but it doesn't seem to copy the bytes correctly. I say "seem" because it's really difficult to diagnose: adding certain printf statements (both inside and outside the loop) "fixes" the problem, and it doesn't hang.
pps: the optimization level doesn't seem to matter: I used the pragma option, and it changed the amount it was wrong by, but no the wrongness.
So, I would like to try and come up with a small program that reproduces the possible bug, but I don't know on what criteria a loop in CMM is put into fcache. Where can I find that sort of thing out?
ps: On my current code, this is the snippet that is causing problems:
while(format[stringIndex] >= '0' and format[stringIndex] <= '9'){ paddingBuffer[paddingIndex++] = format[stringIndex]; // printf("+%c+", format[stringIndex]); stringIndex++; }
It should end up coping one char array to another. It seems to loop the correct amount of times, but it doesn't seem to copy the bytes correctly. I say "seem" because it's really difficult to diagnose: adding certain printf statements (both inside and outside the loop) "fixes" the problem, and it doesn't hang.
pps: the optimization level doesn't seem to matter: I used the pragma option, and it changed the amount it was wrong by, but no the wrongness.
Comments
- I am looking forward to an answer of one of the cracks...
Meanwhile I can recomment to have a look at the pasm compiler output. There you can see, if a part of a routine is in the fcache. The part of the code will be first loaded into cog ram and then be executed.
As far as I know:
A loop can be fcached, if it fits into the cache and if it has no function calls in it. If you use a function like printf(), the loop cannot be in the cache.
My experience with fcache and lmm and cmm was so far, that it worked.
Good Luck, Christof
The rules for what goes into fcache are:
(1) Fcache is only active if compiling with -mfcache (which is implied by -O2 and above, and by -Os in LMM mode). -mno-fcache always disables it.
(2) A loop cannot go into fcache if it is bigger than the fcache size (512 bytes in LMM mode, 256 in other modes).
(3) A loop cannot go into fcache if it contains any branches, including subroutine calls, outside of itself. There is a special provision for recursive functions: see below.
(4) If a loop does contain recursive calls (only) then the compiler checks to see if the entire function can be placed into fcache. The rules for this are pretty much the same as for an individual loop: the function has to be small enough, and cannot contain any calls or branches outside of itself.
(5) If a function is marked as __attribute__((fcache)) then the compiler will try to put the whole function into fcache, following the rules in (4). This is true even if the function is not recursive.
I'd certainly be interested to see if you can figure out what's going on with your bug. My guess off-hand is that the assembler is probably translating one of the CMM mode instructions incorrectly inside the FCACHE region. It's supposed to automatically convert compressed instructions into normal ones, but something may be going wrong there.
Thanks,
Eric
Using -mno-fcache freezes the program
This seems to happen in CMM mode with -Os and -O0, and it happens in LMM mode in -Os but not -O0.
I've attached the offending program. You should be able to run it on any Propeller board with 64kB EEPROM. Download with:
A successful start is
An unsuccessful run freezes after the "!" mark in the welcome message.
I have noticed this problem (namely that -O0 in CMM mode freezes programs), but I've never been able to be relatively sure that it was a problem with the compiler and not my code. I'm fairly confident in this code, however, so I've posted it here.
In CMM mode "-Os" and "-Os -mno-fcache" should be completely identical (fcache code cannot be compressed, so asking for size optimization in CMM also turns off fcache). Also, "-O0" and "-O0 -mno-fcache" should be identical in all cases, since fcache is only enabled when optimization is.
Or perhaps I'm not understanding:
The only one of these cases where -mno-fcache should have any affect on the compiler is LMM -Os.
Eric
My fault. It should be attached to post #4 now.
Eric