Go Down

Topic: Optimization of code for maximum speed, very specific project. (Read 3 times) previous topic - next topic


If your sketch can't keep up,   you could always try moving to a country with 50 Hz electricity.    Like, for example,  New Zealand.    Or one half of Japan ( I forget which half ).

That is thinking outside the box. :)


tickCounter += TIMER_CYCLE_COUNT;

You are chasing a wrong direction here, I think.   You should want to redefined a "tick" so that tick = CycleTime/BrightnessLevels (or, for 8.3ms and 256 brightness levels, about 32 us.)  That means that the clock always ticks by 1 in your ISR.   The actual clock or instruction rate of the cpu ought to be irrelevant.  Sure, at some level it's the limiting factor, but you want to have your code running in a way that it's so much faster than the problem, that there's no actual dependency...

Looking at the code generated when tick and powerDelay are both uint8_t, it looks to be about 480 instructions.  32 us is about 512 instructions.  Now, every ISR execution doesn't execute all the instructions, and all the instructions are not one cycle, so it's hard to tell whether this would actually be fast enough.  It does indicate (to me) a couple of things:
1) It would be pretty close; certainly close enough to worry about.
2) wider math (32bit tick and powerDelay) probably isn't going to work at all. (1100 instructions!  (odd that it isn't more.))
3) going to, say, 100 ticks/halfcycle instead of 256 ticks/halfcycle, would probably give you all the breathing room you need.

I see what you are getting at now, thanks.  I didn't understand how you expected me to put values of 256 or more into a byte.  I'll have to see what I can to rearrange this.  The latest code is attached.


Similarly, since serial messages are only occasional and not more than every 50ms, while AC cycles happen every 1/120 s (8.3ms),
get rid your calculations of powerDelay[] in ZeroCrossDetected and move them into the serial receive code.

Done. I only update the powerDelay values after I have read in a new set of channel values, see the updatePowerDelayValues() in the code.  I'm turning the interrupts off during this process and I'm not sure if that is a good or bad idea.

I asked this next question earlier and I think I've seen to conflicting "answers" can someone give me the straight poop (I've changed the code this is no longer true but I would like to know)?  "Given that the powerDelay array is only assigned values inside one of the ISRs and only read from the other ISR and the ISRs are not nested:  Can I remove the volatile attribute from the declaration?  That should give me a few extra cycles in speed shouldn't it?"

You can.  You shouldn't.  It won't make any difference...

In each ISR each element of powerDelay is accessed just once (read in one ISR; written in the other).  Removing volatile only helps when there are multiple accesses.  Removing volatile eliminates redundant loads from memory but there aren't any.



This would get better if powerDelay isn't volatile, and if it's smaller, but it still doesn't need to happen every half-cycle.
Or you could look at making the copy into a memcpy() call, which would "short circuit" the (correct) volatile declarations.

Maybe I'm just reading more into the second one than is really there.


Apr 06, 2013, 03:35 am Last Edit: Apr 06, 2013, 03:41 am by zparticle Reason: 1
Okay, random mode, reading data from Vixen, zero cross detection and setting the powerDelay values all work as long as I set the prescaler to 8 and TIMER_CYCLE_COUNT to 100. However in Vixen mode the channels don't turn on until the channel values reach about 128 out of the 255 possible.  I had a lot of really stupid bugs in there.  Working on this stuff when I'm very tired has proven to be a bad choice, lol.

Now I just have to figure out why the light don't come on until around 128 and they don't seem to change intensity.  Attached is the latest code.


Okay the code is now working! Thanks for the help everyone.  Boy was I going about this the wrong way.  Code is attached.

Go Up