Assigning locally declared int values to global int values
pmrobert
Posts: 673
For cog profiling purposes I'm just trying to capture the number of CNTs elapsed in each pass through a loop. Nothing tricky, just "start_cnt = CNT;" at the beginning of the loop and "end_cnt = CNT; calc_loops = end_cnt - start_cnt;" at the end. If I declare all variables globally and volatile, it works fine. If I try and make end_cnt and start_cnt variables local to the cog I'm profiling, the global volatile int "calc_loops" does not get assigned the value of "end_cnt - start_cnt" - it's always 0. what am I missing? I know this is minor but this is a rather large, time sensitive program and every byte counts and keeping the global volatiles down to a minimum helps size and speed. Oh, they're all declared as
Any hints or comments would be greatly appreciated. As I've said, I can use the working version but I'd like to know what I'm doing or assuming that's breaking the second case.
Thanks in advance!
-Mike
volatile uint_fast32_t calc_loops = 0; volatile uint_fast32_t start_cnt = 0; volatile uint_fast32_t end_cnt = 0;in the working version and the volatile start_cnt and end_cnt declarations are commented out and placed in the local cog code without the volatile designation in the nonworking version. The compiler complains of nothing in either case. I'm using LMM and the pruning commands in the batch file that compiles this as follows:
del %1\%3\%2.elf propeller-elf-gcc.exe -I . -L . -I %1/SimpleLibraries/Utility/libsimpletools -L %1/SimpleLibraries/Utility/libsimpletools/%3/ -I %1/SimpleLibraries/TextDevices/libsimpletext -L %1/SimpleLibraries/TextDevices/libsimpletext/%3/ -I %1/SimpleLibraries/Protocol/libsimplei2c -L %1/SimpleLibraries/Protocol/libsimplei2c/%3/ -I %1/SimpleLibraries/TextDevices/libfdserial -L %1/SimpleLibraries/TextDevices/libfdserial/%3/ -o %3/%2.elf -O2 -m%3 -Wall -m32bit-doubles -fno-exceptions -std=c99 -ffunction-sections -fdata-sections -Wl,--gc-sections %2.c -lsimpletools -lsimpletext -lsimplei2c -lfdserial -lsimpletools -lsimpletext -lsimplei2c -lsimpletools -lsimpletext -lsimpletools if %errorlevel% equ 0 goto success pause exit :success propeller-load -q -b c3 -e -r %1\%3\%2.elf exit
Any hints or comments would be greatly appreciated. As I've said, I can use the working version but I'd like to know what I'm doing or assuming that's breaking the second case.
Thanks in advance!
-Mike
Comments
Can you provide minimal example code that illustrates your problem?
Describing what you're doing is not enough detail (for me at least).
The appropriate lines are commented out as regards Case 1 or Case 2. Thanks for looking at it.
The code below works for me in all cases.
CMM or LMM, -O2 or -O3, with or without pruning, with or without USEGLOB
Here's the cut of what I thought wasn't working (and isn't - in the much larger project I'm working on).
One thing to remember is that simpleterm functions are single cog only. If you need multiple cog printing, use fdserial like I did.
Are you using GCC developer's indent style? Just curious.
-Mike, TIA!
I plugged calc() and test() into the old program, and am getting build errors.
Please post your entire file if possible.
Here's everything I could think of, .map and .asm to follow. This version code (USEGLOB is not defined) exhibits the problem. If USEGLOB is defined cnts_per_calc_loop is reported properly, without USEGLOB cnts_per_calc_loop returns what looks like the actual CNT. Many, many items are stubs but the parts referenced by the questionable code are intact. It will read data from the upper 32K of a 64K EEPROM so the tables will be a bunch of junk or all 0s. I ripped out a bunch of perfectly functioning code but this did not help anything at all. The only condition that makes it act weird is if, and only if, that "fuellresult = ..." section is active, i.e., not commented out. I tried CMM, LMM, pruning enabled/disabled, optimizations enabled/disabled, etc. That longish equation seems to be what makes it malfunction.
Here's an activity log generated from the PC app:
Here's the batch file that compiles it:
EFI20140716.asm
I'll have a look in the morning when I'm fresh.
SimpleIDE has a zip/archive that makes posting such projects a snap. It's ok to use other environments of course. I use vim and the command line when not writing Propeller programs unless a reasonable vendor package is available. I owe it to everyone to use the programs Parallax and I publish for Propeller. I do. Sometimes the dog-food is pretty bad, most of the time it tastes like candy (to me at least).
pmrobert.zip
If you compile with the -S option you can save the intermediate assembly file. The assembly file shows that your test routine is run from FCACHE since it is so small. I think the problem may be a timing issue, where the test routine is setting the lock before calc can test it for 0. That is, test is clearing and setting lock so quickly that calc never has a chance to see it with a value of 0. When you change some variables from local to global it probably changes the timing enough where calc gets to run.
Can you add a run count for calc and test, and print that out periodically? You may see that calc never runs a single loop.
-Mike
I have taken out all the "lock" related references, disabled all other functions and tried every optimization with various combinations of var declaration. volatile global & volatile local work, with the global being a bit faster. local nonvolatile gives that same erroneous result unless I compile with -O0 or comment out the fuelresult= equation at the end of calc. I can live with that but am unsettled as to the "why doesn't it work and will this bite me in the butt again?" issue as well as the idea that using nonvolatile locals should be the fastest and smallest implementation of my attempts at profiling measurement. As Dave says, "It shouldn't matter if your start_cnt and end_cnt variables are volatile or global, or whether they are static or stack variables." I have 3 defines, "CONDITION_x" in the attached version with the results of each. Any ideas?