node
node copied to clipboard
child_process: improve spawn performance on Linux
deps: V8: cherry-pick 1a782f6543ae
Original commit message:
[base] add build flag to use MADV_DONTFORK
Embedders like Node.js and Electron expose fork(2)/execve(2) to their
users. Unfortunately when the V8 heap is very large, these APIs become
rather slow on Linux, due to the kernel needing to do all the
bookkeeping for the forked process (in clone's dup_mmap and execve's
exec_mmap). Of course, this is useless because the forked child thread
will never actually need to access the V8 heap.
Add a new build flag v8_enable_private_mapping_fork_optimization which
marks all pages allocated by OS::Allocate as MADV_DONTFORK. This
improves the performance of Node.js's fork/execve combination by 10x on
a 600 MB heap.
Fixed: v8:7381
Change-Id: Ib649f774d4a932b41886313ce89acc369923699d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4602858
Commit-Queue: Michael Lippautz <[email protected]>
Reviewed-by: Michael Lippautz <[email protected]>
Cr-Commit-Position: refs/heads/main@{#88447}
Refs: https://github.com/v8/v8/commit/1a782f6543ae999bf9e497e23042af0b70191f10
child_process: improve spawn performance on Linux
Speed up child_process.spawn by enabling the new V8 build flag which makes fork/exec faster.
Here are the results of running the existing benchmark. Note that this optimization helps more for applications with larger heaps, so this is somewhat of an underestimate of the real world performance benefits.
$ ./node benchmark/compare.js --runs 15 \
--new ./node \
--old ~/node-v20/out/Release/node \
--filter params child_process > cpr
$ node-benchmark-compare cpr
confidence improvement (***)
methodName='exec' n=1000 *** 60.84 % ±5.43%
methodName='execFile' n=1000 *** 53.72 % ±3.33%
methodName='execFileSync' n=1000 *** 9.10 % ±0.84%
methodName='execSync' n=1000 *** 10.44 % ±0.97%
methodName='spawn' n=1000 *** 53.10 % ±2.90%
methodName='spawnSync' n=1000 *** 8.64 % ±1.22%
0.01 false positives, when considering a 0.1% risk acceptance (***)
Fixes: https://github.com/nodejs/node/issues/25382 Fixes: https://github.com/nodejs/node/issues/14917 Refs: https://github.com/nodejs/performance/issues/93 Refs: https://github.com/nodejs/performance/issues/89
Review requested:
- [ ] @nodejs/gyp
- [ ] @nodejs/v8-update
CI: https://ci.nodejs.org/job/node-test-pull-request/52358/
V8 CI: https://ci.nodejs.org/job/node-test-commit-v8-linux/nodes=benchmark-ubuntu2204-intel-64,v8test=v8test/5405/
V8 CI: https://ci.nodejs.org/job/node-test-commit-v8-linux/nodes=rhel8-s390x,v8test=v8test/5405/
V8 CI: https://ci.nodejs.org/job/node-test-commit-v8-linux/nodes=rhel8-ppc64le,v8test=v8test/5405/
CI: https://ci.nodejs.org/job/node-test-pull-request/52359/
V8 CI: https://ci.nodejs.org/job/node-test-commit-v8-linux/nodes=benchmark-ubuntu2204-intel-64,v8test=v8test/5406/
V8 CI: https://ci.nodejs.org/job/node-test-commit-v8-linux/nodes=rhel8-s390x,v8test=v8test/5406/
V8 CI: https://ci.nodejs.org/job/node-test-commit-v8-linux/nodes=rhel8-ppc64le,v8test=v8test/5406/
V8 CI: https://ci.nodejs.org/job/node-test-commit-v8-linux/nodes=benchmark-ubuntu2204-intel-64,v8test=v8test/5407/
V8 CI: https://ci.nodejs.org/job/node-test-commit-v8-linux/nodes=rhel8-s390x,v8test=v8test/5407/
V8 CI: https://ci.nodejs.org/job/node-test-commit-v8-linux/nodes=rhel8-ppc64le,v8test=v8test/5407/
CI: https://ci.nodejs.org/job/node-test-pull-request/52365/
CI: https://ci.nodejs.org/job/node-test-pull-request/52372/
CI: https://ci.nodejs.org/job/node-test-pull-request/52375/
Landed in e7a1fab25f7be9fc470aae4927b910d2b75e37dc...7eafd2f7e88cef9923f8c90092e75cf0c0bf0aa8
This commit does not land cleanly on v18.x-staging
and will need manual backport in case we want it in v18.