I have opened https://code.google.com/p/v8/issues/detail?id=3967 to address the high CPU usage.
Regards Michael On Thursday, 8 January 2015 17:34:01 UTC, [email protected] wrote: > > Hello folks, my name is Michael Tunnicliffe and I work for IBM. I have > been working on the PowerPC port of V8 along with Andrew Low and a number > of other colleagues. Recently, I have also been writing some code to use > the V8 API and have come across something that looks a bit strange to me. > > *Summary* > I have been particularly interested in the profiling API (CpuProfiler) and > have a developed some code that starts profiling via this API. I was > surprised to see that when doing so, the CPU usage of one of the cores on > my machine would max out. > > My colleagues and I first spotted this on V8 3.14 running on Linux x64 and > invoking CpuProfiler->StartProfiling(...). I have since recreated similar > symptoms on a recent version of bleeding_edge (although I suspect the > behaviour is actually slightly different -- ie in 3.14 there are regular > yields to the scheduler and 3.21+ there may not be (I am still trying to > confirm)). > > *Analysis/Details* > On V8 3.14, I did some analysis with perf and code inspection to narrow > the behaviour down to ProfilerEventsProcessor::Run(). It contains a loop > which checks and performs some work (processes a sample and/or code events) > then yields CPU when it has done some work. The result of this is it > consumes any spare CPU that it can find on the core it is scheduled on > which pegs it at 100%. Since there is a yield there, it will relinquish > time slices to other processes, but this is not obvious to the user and > probably has other undesirable side-effects. > > Monitoring the CPU consumption with top, an threads view turned on, > "v8:ProfEvntProc" can be seen consuming 100% of one core. Capturing a > profile with perf for 15 seconds, the top consuming stack, with the vast > majority of samples, is spending them mostly in shed_yield (and related > code) and ProfilerEventsProcessor::Run(). (This is what lead me to look at > that code). > > I also noticed that profiling using the --prof command-line option does > not result in this behaviour. Looking through the code, I see that the > processing thread is different (and this is evident when monitoring the CPU > in top as well, since the thread is named differently ("v8:Profiler")), and > instead of keeping track of the data like CpuProfiler, it logs to file. In > the specific test and setup I have, the "v8:ProcEvntProc" thread takes > ~100% of one core and "v8:Profiler" takes ~15% of one core. > Looking at the code, the processing thread behind --prof (from log.cc) is > using a semaphore to control when the processing thread wakes up to do some > work. > > My colleagues and I spotted that the CpuProfiler has undergone some rework > in 3.21 and later, so I looked at the code for later versions (including > 3.28 and a recent version of bleeding_edge). It looks like > ProfilerEventsProcessor::Run() has been restructured to control the sample > interval, and in doing so the yield has been removed. I have recreated the > 100% CPU behaviour on a recent bleeding_edge version of V8 (albeit through > some hackery), and I am in the process of trying to confirm whether this is > a real tight loop that won't relinquish time-slices. > > On both 3.14 and recent bleedging_edge, a poor man's hack can be > introduced to sleep for a number of microseconds when there is no other > work to do, to confirm that the CPU usage will drop down to around 15% > (similar to that seen when using --prof). > > *Caveats* > I've only been looking at this particular code for a relatively short > period, so I may have made some erroneous assumptions -- I'd welcome > corrections (and forgiveness) for any mistakes. I have tried to back up my > understanding with evidence, however, my tests have been somewhat limited > at this point (eg: mostly on Linux). > > *Questions* > * Are you folks already aware of this behaviour / does it happen for you > as well? > > * Are you aware of a design reason to avoid sleeping/blocking in > ProfilerEventsProcessor::Run()? > > * Would you folks consider a patch to bring the behaviour of the > v8:ProfEvntProc thread in line with v8:Profiler? Are there any particular > important concerns/constraints that such a patch would need to address (eg: > throughput or responsiveness requirements on processing queued data)? > > *Some thoughts on a possible solution/change, ignore as necessary* *;)* > On 3.14 it seems like a semaphore (like the one in log.cc) would be > appropriate -- wait when there's no more work, signal when there's a > completed sample or enough code events to be worth waking for. > On 3.21+, where there is a timer in this code and it drives sample > generation, a different approach would be necessary. Perhaps a timed > conditional wait of some kind (so the thread could be woken to process code > events if needed, eg to prevent the queue getting too large, and so a > sample could be taken if the timeout is reached.) > > Thanks! > Michael > -- -- v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev --- You received this message because you are subscribed to the Google Groups "v8-dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
