Hi, What is the importance of heartbeat in Cog? What happens if heartbeat frequency is unstable or low? Concerning running Cog in Android: most of the time (between screen/hardware button presses) an activity (and any of Cog code) is just not running. I can give it periodic timer events, but if they are too frequent then CPU load is higher therefore battery drains faster. Cog gets control only when some external event is ready to be processed. Plus, I am not sure whether external signals are available to Android programs same way they are in Linux. Is it possible to replace external signal-driven heartbeat with some synchronous action invoked in the interpreter every N bytecodes, or just one beat at interpreter entry, one at exit? Sorry if my question is complete nonsense, but I feel like I need to ask anyway ;) Andeas' hack on classic VM (which is currently used in Android) was to return from the interpreter once the VM internal process queue is empty. I am thinking that instead of this I could create a special display module, and switch in and out the VM on calls to ioGetEvent. But classic VM did not have heartbeat, did it? Thanks. PS I realize that in such mode internal process management by the Cog VM is impaired, but my goal is to use it mostly for GUI anyway and rely more on host processes and threads. PPS I am interested in Stack VM only since JIT for ARM may not even exist at this moment. -- Dimitry Golubovsky Anywhere on the Web |
Hi Dimitry, On Wed, Jul 6, 2011 at 12:00 PM, Dimitry Golubovsky <[hidden email]> wrote:
The heartbeat determines a) the clock frequency, how fast the microsecond clock advances in time, and b) how often the VM checks for input, delays expiring, external semaphores being signalled etc. If the frequency is unstable or low the clock resolution will be poor, delays will fire erratically and input won't be responded to promptly.
Note that a) is strictly optional. An alternative architecture, as used in the VisualWorks VM, would move checking for delays expiring to the platform, using some kid of interrupt-driven expiring timer (on Windows spawining a thread that waits with a timeout on an OS semaphore, the timeout being the time to the next delay, on Unix a call to nanosleep in some thread, or use of setitimer, etc). Then there is no need for the heartbeat to wake up while the system is inactive. Instead when inactive the Vm enters some efficient blocking sleep waiting on any input events, and if a pending delay expires, the delay code breaks the VM out of its blocking wait. But the Squeak VM has been written to check for expiring delays as part of its event check. It maintains the time of the next expiring delay and in the Cogit and Stack VMs checks it in checkForEventsMayContextSwitch: (see nextWakeupUsecs) and in the Interpreter checks it in checkForInterrupts (see nextWakeupTick).
So changing this (which I think is a good idea; it works well for VW) requires some effort.
You could safely lower the frequency when the VM is inactive, and raise it when active. You just need to be aware of the pending delay issue and not e.g. lower the frequency to 1Hz when the next delay is scheduled to fire in 10ms.
No it is not, not without performance impact. The heartbeat is a far more efficient way of causing the VM to break-out of Smalltalk bytecode execution than a counter. The counter itself is expensive; a read-modify-write cycle in some high-dynamic-freqency operation such as frame building. The counter also suffers from a really bad bug in that its frequency depends on what Smalltalk is being executed. If the system is executing long-running large integer primitives then the counter counts slowly and the system is unresponsive as a result. If the system is executing high send frequency code then the counter counts very fast and the system wastes cycles checking for interrupts, or at least checking whether it should check for interrupts.
No, these are excellent questions. The answers are a little tricky however :)
-- best, Eliot |
Allow me to give some more knowledge as I struggled with this for a decade or so. Now I believe in VW as I looked last week for another reason is that when a yield happens it appears to want to run the next best process. That can lead to no process runnable so it then waits for an interrupt which can be from a timer, or socket, file, ui etc... Then the VW is woken to service that Now in Squeak we had ioRelinquishProcessorForMicroseconds which is run as the lowest priority process and basically means go to sleep. So how long? Good questions. Well a decade back that was some magic number that had no bearing on reality plus the non-real-time linux system might sleep for 100 ms, bad.. Anyway that evolved over time and the first bread crumb is... getNextWakeupTick() That is the next known time from the Delay logic to wake up the VM to service a Delay. If you rummage around a bit you'll find time now - getNextWakeupTick() could be in the future, could be zero, could be slightly in the past. You need to handle all cases. BTW I know that sometimes it can be now, but the Smaltlalk code isn't quite ready to make the Delay run able so you might get 50 calls saying delay fires now or in the past, but we are idle.... Bonus points if you can figure out why.. Bread crumb two, In the past Morphic was responsible for pounding the VM every 1/60 or so polling for UI events. But In the current Pharo version this has been fixed which led to a problem with the Mac VM not sufficiently polling for UI events, see bread crumb three. Bred crumb three, some VM's need time to service/poll I/O this was done by stuff that Eliot mentioned earlier which based on interpreter code running would vary in the call times, also see two and I can't recall with Esteban and I did to fix the issue. (4) If the VM is sleeping why fire the heartbeat. I looked at this but with morphic firing every 12-16 ms the cost of fixing up the thread was more expensive from a CPU time than not doing it. But this should be revisted now that Pharo doesn't poll every 12 ms, all I did was suspend the pthread, resume. But maybe you can alter the delay time? Mmm set the next timer fire to be 234 ms out as that is the next fire time for the Delay, if we get an interrupt then resume the clock. -- =========================================================================== John M. McIntosh <[hidden email]> Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com =========================================================================== |
Free forum by Nabble | Edit this page |