GithubHelp home page GithubHelp logo

Comments (8)

kiddkai avatar kiddkai commented on June 18, 2024

I did some debugging locally, and I think I figured out the reason that caused this issue:

  • Code will be run in the same main thread under sync mode.
  • Code will be run in a different thread under async mode.

In v8, when we use the create CPU profiler method from v8, it starts a CPU Profiler, which creates a Sampler that binds to the thread_id of the Isolate. And start a new thread sending sigprof to collect samples periodically.

https://github.com/v8/v8/blob/main/src/libsampler/sampler.cc#L207-L219

It seems like when the callback is triggered by uv, it's in a different thread, so the sampler does not collect samples from that thread.

image

Therefore, the sampler "thinks" that it's running an external (program) rather than the actual js code we evaluate.


I think fixing this problem can be tricky, I will dig further to see if I can find a solution to let the sampler somehow collect samples from the new thread and use the info from the original Isolate thread to construct the CPU Profile...

from isolated-vm.

laverdet avatar laverdet commented on June 18, 2024

Whew that is tricky. Do you think it makes sense to rethink the API, and make this an option in the isolate's constructor arguments? This would be similar to the inspector option. There's actually a very nice place to land StartProfiling and StopProfiling.. in Executor::CpuTimer. This class manages the clock bookkeeping for cpuTime and is invoked when an isolate starts or stops, and is always invoked from the processing thread (which may be different each time an isolate is invoked).

from isolated-vm.

kiddkai avatar kiddkai commented on June 18, 2024

Yeah, the current API is no longer valid.

Invoking from the Executor::CpuTimer does make sense in terms of start/stop tracking samples.

I think there are two challenges to doing it:

  1. Each startProfiling + stopProfiling call generate 1 CPU profile, so each pause+resume will generate one CPU profile if we do it. I guess I can try to find a way to contact/merge the new profile into a single one when profiling mode is true.
  2. When to dispose/stop the CPU profiler can also be tricky.

Currently, what I am thinking is to provide an API in the Isolate instance to add a startProfiling and stopProfiling, method. And those methods only sets a state in the isolate. When the executor lock/unlock, it checks the state and decides if it needs to start or stop the profiler.

I will try to come up with a POC today about this solution.

from isolated-vm.

kiddkai avatar kiddkai commented on June 18, 2024

Executor::Lock seems a good place to start/stop profiling if env has CPU profiling enabled.

from isolated-vm.

kiddkai avatar kiddkai commented on June 18, 2024

image

Got the POC working locally to start to collect samples when resume, now I need to work out how transfer and merge those data together.

from isolated-vm.

kiddkai avatar kiddkai commented on June 18, 2024

Hi @laverdet ,

I've been working on how to capture the profiles from different thread and was able to generate some profiles
in my own defined classes.

This is the API design I have locally:

    isolate.startCpuProfiler("test");

    // const promises = [];
    for (let i = 0; i < 2; i++) {
        const log = `${n} -> ${i} done`;
        const context = await isolate.createContext();
        await context.eval(`
            1 + 1
        `, {
            filename: 'foo.js',
            promise: true,
        }).then(() => {
            console.log(log)
        });
        context.evalSync(`
            1 + 1
        `, {
            filename: 'foo.js',
            promise: true,
        }).then(() => {
            console.log(log)
        });

        context.release();

        // await timeout();
        
        // promises.push(res);
    }

    // await Promise.all(promises);
    // setTimeout(() => {
    const profiles: ProfileWithThreadInfo[] = await isolate.stopCpuProfiler('test');

do you think it make sense to return each profile from different threads as an array?
or return it as a single profile object, and the thread info is injected into the single CPU profile itself; the timeline may look weird by doing this since multiple threads can execute different things at the same time.

from isolated-vm.

kiddkai avatar kiddkai commented on June 18, 2024

One profile info per thread without merging them makes more sense to me. The consumer can export them individually to load them into different tools.
Or even create their custom parallel CPU profile viewing tool to check the invocation timeline behaviours.

from isolated-vm.

kiddkai avatar kiddkai commented on June 18, 2024

Hi @laverdet , this is the PR to address this issue: #336

from isolated-vm.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.