Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: always compile and store code cache for native modules #24950

Closed
wants to merge 4 commits into from

Conversation

joyeecheung
Copy link
Member

src: remove code cache integrity check

In preparation of sharing code cache among different threads -
we simply rely on v8 to reject invalid cache, since there isn't
any serious consequence when the cache is invalid anyway.

src: always compile and store code cache for native modules

This patch changes the NativeModuleLoader to always try to find
code cache for native modules when it compiles them, and always
produce and store the code cache after compilation. The cache
map is protected by a mutex and can be accessed by different
threads - including the worker threads and the main thread. Hence any
thread can reuse the code cache if the native module has already
been compiled by another thread - in particular the cache of the
bootstrappers and per_context.js will always be hit when a new thread
is spun.

This results in a ~6% startup overhead in the worst case
(when only the main thread is launched without requiring any additional
native module - it now needs to do the extra work of finding and
storing caches), which balances out the recent improvements by moving
the compilation to C++, but it also leads to a ~60% improvement in
the best case (when a worker thread is spun and requires a lot of native
modules thus hitting the cache compiled by the main thread).

Local benchmark results:

                                                                                   confidence improvement accuracy (*)   (**)  (***)
 misc/startup.js mode='process' script='benchmark/fixtures/require-cachable' dur=1        ***     -6.80 %       ±0.77% ±1.02% ±1.34%
 misc/startup.js mode='process' script='test/fixtures/semicolon' dur=1                    ***     -4.90 %       ±0.82% ±1.10% ±1.43%
 misc/startup.js mode='worker' script='benchmark/fixtures/require-cachable' dur=1         ***     63.13 %       ±1.58% ±2.12% ±2.79%
 misc/startup.js mode='worker' script='test/fixtures/semicolon' dur=1                     ***     56.20 %       ±1.33% ±1.78% ±2.33%
Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines

In preparation of sharing code cache among different threads -
we simply rely on v8 to reject invalid cache, since there isn't
any serious consequence when the cache is invalid anyway.
This patch changes the NativeModuleLoader to always try to find
code cache for native modules when it compiles them, and always
produce and store the code cache after compilation. The cache
map is protected by a mutex and can be accessed by different
threads - including the worker threads and the main thread. Hence any
thread can reuse the code cache if the native module has already
been compiled by another thread - in particular the cache of the
bootstrappers and per_context.js will always be hit when a new thread
is spun.

This results in a ~6% startup overhead in the worst case
(when only the main thread is launched without requiring any additional
native module - it now needs to do the extra work of finding and
storing caches), which balances out the recent improvements by moving
the compilation to C++, but it also leads to a ~60% improvement in
the best case (when a worker thread is spun and requires a lot of native
modules thus hitting the cache compiled by the main thread).
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. labels Dec 10, 2018
src/node_native_module.cc Show resolved Hide resolved
src/node_native_module.cc Show resolved Hide resolved
src/node_native_module.cc Outdated Show resolved Hide resolved
@joyeecheung
Copy link
Member Author

@addaleax Thanks for the review, updated. Also updated the emplace() calls since gcc 4.9.4 needs the pointers to be moved before the call, and updated the test to pass the --worker test suit since compileWithCache is no longer guaranteed to be empty when a worker thread is spun (that's the whole point of this patch :p)

PTAL.

Also cc @nodejs/process @nodejs/build-files

CI: https://ci.nodejs.org/job/node-test-pull-request/19412/
Benchmark CI: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/282/

@BridgeAR BridgeAR added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Dec 12, 2018
@joyeecheung joyeecheung removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Dec 12, 2018
@joyeecheung
Copy link
Member Author

joyeecheung commented Dec 12, 2018

Removing author-ready because this needs at least one more approval to land before next week.

From the previous benchmark CI:

                                                                                   confidence improvement accuracy (*)   (**)  (***)
 misc/startup.js mode='process' script='benchmark/fixtures/require-cachable' dur=1        ***     -7.38 %       ±1.09% ±1.46% ±1.90%
 misc/startup.js mode='process' script='test/fixtures/semicolon' dur=1                    ***     -5.12 %       ±0.79% ±1.06% ±1.37%
 misc/startup.js mode='worker' script='benchmark/fixtures/require-cachable' dur=1         ***     54.77 %       ±1.42% ±1.91% ±2.50%
 misc/startup.js mode='worker' script='test/fixtures/semicolon' dur=1                     ***     48.22 %       ±3.27% ±4.40% ±5.82%

Resume CI: https://ci.nodejs.org/job/node-test-pull-request/19454/

@BridgeAR
Copy link
Member

@joyeecheung the label is not meant as ready to land but the author is done. Missing LGs are absolutely fine while having the author ready label applied :-)

@joyeecheung
Copy link
Member Author

@BridgeAR

the label is not meant as ready to land but the author is done. Missing LGs are absolutely fine while having the author ready label applied :-)

That seems to contradict the label description:

PRs that have at least two approvals, no pending requests for changes, and a CI started.

And the collaborator guide:

at least two Collaborators approved the PR (one Collaborator approval is enough if the pull request has been open for more than 7 days).

@BridgeAR
Copy link
Member

@joyeecheung

That seems to contradict the label description:

The label was not up to date. It's fixed now.

And the collaborator guide:

Thanks! Seems like I missed that in #24893. I am opening a PR to fix that right away.

@joyeecheung
Copy link
Member Author

@joyeecheung
Copy link
Member Author

Landed in ceb6635 and 0858e5d

joyeecheung added a commit that referenced this pull request Dec 18, 2018
In preparation of sharing code cache among different threads -
we simply rely on v8 to reject invalid cache, since there isn't
any serious consequence when the cache is invalid anyway.

PR-URL: #24950
Reviewed-By: Anna Henningsen <anna@addaleax.net>
joyeecheung added a commit that referenced this pull request Dec 18, 2018
This patch changes the NativeModuleLoader to always try to find
code cache for native modules when it compiles them, and always
produce and store the code cache after compilation. The cache
map is protected by a mutex and can be accessed by different
threads - including the worker threads and the main thread. Hence any
thread can reuse the code cache if the native module has already
been compiled by another thread - in particular the cache of the
bootstrappers and per_context.js will always be hit when a new thread
is spun.

This results in a ~6% startup overhead in the worst case
(when only the main thread is launched without requiring any additional
native module - it now needs to do the extra work of finding and
storing caches), which balances out the recent improvements by moving
the compilation to C++, but it also leads to a ~60% improvement in
the best case (when a worker thread is spun and requires a lot of native
modules thus hitting the cache compiled by the main thread).

PR-URL: #24950
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@MylesBorins
Copy link
Contributor

This does not land cleanly on v11.x, would someone be willing to backport?

@BridgeAR
Copy link
Member

BridgeAR commented Jan 9, 2019

Ping @joyeecheung

addaleax pushed a commit that referenced this pull request Jan 14, 2019
In preparation of sharing code cache among different threads -
we simply rely on v8 to reject invalid cache, since there isn't
any serious consequence when the cache is invalid anyway.

PR-URL: #24950
Reviewed-By: Anna Henningsen <anna@addaleax.net>
addaleax pushed a commit that referenced this pull request Jan 14, 2019
This patch changes the NativeModuleLoader to always try to find
code cache for native modules when it compiles them, and always
produce and store the code cache after compilation. The cache
map is protected by a mutex and can be accessed by different
threads - including the worker threads and the main thread. Hence any
thread can reuse the code cache if the native module has already
been compiled by another thread - in particular the cache of the
bootstrappers and per_context.js will always be hit when a new thread
is spun.

This results in a ~6% startup overhead in the worst case
(when only the main thread is launched without requiring any additional
native module - it now needs to do the extra work of finding and
storing caches), which balances out the recent improvements by moving
the compilation to C++, but it also leads to a ~60% improvement in
the best case (when a worker thread is spun and requires a lot of native
modules thus hitting the cache compiled by the main thread).

PR-URL: #24950
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@addaleax
Copy link
Member

Lands cleanly now 👍

refack pushed a commit to refack/node that referenced this pull request Jan 14, 2019
In preparation of sharing code cache among different threads -
we simply rely on v8 to reject invalid cache, since there isn't
any serious consequence when the cache is invalid anyway.

PR-URL: nodejs#24950
Reviewed-By: Anna Henningsen <anna@addaleax.net>
refack pushed a commit to refack/node that referenced this pull request Jan 14, 2019
This patch changes the NativeModuleLoader to always try to find
code cache for native modules when it compiles them, and always
produce and store the code cache after compilation. The cache
map is protected by a mutex and can be accessed by different
threads - including the worker threads and the main thread. Hence any
thread can reuse the code cache if the native module has already
been compiled by another thread - in particular the cache of the
bootstrappers and per_context.js will always be hit when a new thread
is spun.

This results in a ~6% startup overhead in the worst case
(when only the main thread is launched without requiring any additional
native module - it now needs to do the extra work of finding and
storing caches), which balances out the recent improvements by moving
the compilation to C++, but it also leads to a ~60% improvement in
the best case (when a worker thread is spun and requires a lot of native
modules thus hitting the cache compiled by the main thread).

PR-URL: nodejs#24950
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@BridgeAR BridgeAR mentioned this pull request Jan 16, 2019
BridgeAR pushed a commit to BridgeAR/node that referenced this pull request Jan 16, 2019
In preparation of sharing code cache among different threads -
we simply rely on v8 to reject invalid cache, since there isn't
any serious consequence when the cache is invalid anyway.

PR-URL: nodejs#24950
Reviewed-By: Anna Henningsen <anna@addaleax.net>
BridgeAR pushed a commit to BridgeAR/node that referenced this pull request Jan 16, 2019
This patch changes the NativeModuleLoader to always try to find
code cache for native modules when it compiles them, and always
produce and store the code cache after compilation. The cache
map is protected by a mutex and can be accessed by different
threads - including the worker threads and the main thread. Hence any
thread can reuse the code cache if the native module has already
been compiled by another thread - in particular the cache of the
bootstrappers and per_context.js will always be hit when a new thread
is spun.

This results in a ~6% startup overhead in the worst case
(when only the main thread is launched without requiring any additional
native module - it now needs to do the extra work of finding and
storing caches), which balances out the recent improvements by moving
the compilation to C++, but it also leads to a ~60% improvement in
the best case (when a worker thread is spun and requires a lot of native
modules thus hitting the cache compiled by the main thread).

PR-URL: nodejs#24950
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@MylesBorins MylesBorins mentioned this pull request Jan 24, 2019
kvakil added a commit to kvakil/node that referenced this pull request Mar 14, 2023
This behavior of sometimes returning the function & other times
returning the code cache was removed a long time ago in the referenced
PR, as evinced by the return type `MaybeLocal<Function>`. Remove these
incorrect comments.

Refs: nodejs#24950
nodejs-github-bot pushed a commit that referenced this pull request Mar 16, 2023
This behavior of sometimes returning the function & other times
returning the code cache was removed a long time ago in the referenced
PR, as evinced by the return type `MaybeLocal<Function>`. Remove these
incorrect comments.

Refs: #24950
PR-URL: #47083
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
targos pushed a commit that referenced this pull request Mar 18, 2023
This behavior of sometimes returning the function & other times
returning the code cache was removed a long time ago in the referenced
PR, as evinced by the return type `MaybeLocal<Function>`. Remove these
incorrect comments.

Refs: #24950
PR-URL: #47083
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
danielleadams pushed a commit that referenced this pull request Jul 6, 2023
This behavior of sometimes returning the function & other times
returning the code cache was removed a long time ago in the referenced
PR, as evinced by the return type `MaybeLocal<Function>`. Remove these
incorrect comments.

Refs: #24950
PR-URL: #47083
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants