Each instance starts billing as soon as it's started. It rounds up to the hour - so if you start it and run it for five minutes and stop it, you get billed 1 hour. If you run it for 55 minutes and stop it, you get billed for 1 hour. If you run it for 65 minutes and stop it, you get billed for 2 hours.
If you stop and start the same exact instance 5 times in an hour, you get billed for 5 hours! Beware.
The billing goes from the time the instance entered the started state and till it enters the stopping state. So as long as you tell it to stop, you're OK, it doesn't have to get all the way to stopped. You can see the instance start time in the instance metadata and through the console.
There is no averaging across instances - each instance is completely separate from a billing point of view. So if you run two instances for 5 minutes each, that's 2 hours of bill.
We implemented a highly dynamic compile cloud product and so after verifying all these details with our Amazon account team we wrote a reasonably complex scaling algorithm that when it runs and determines how many instances are running and how many we really need, looks for instances near the end of their hour lifecycle to drop and never drops anything unless it's in the 50+ minute mark of a given hour.