From 7eafd2f7e88cef9923f8c90092e75cf0c0bf0aa8 Mon Sep 17 00:00:00 2001 From: Keyhan Vakil Date: Thu, 22 Jun 2023 17:08:58 +0000 Subject: [PATCH] child_process: improve spawn performance on Linux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. ```console $ ./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 PR-URL: https://github.com/nodejs/node/pull/48523 Refs: https://github.com/v8/v8/commit/1a782f6543ae999bf9e497e23042af0b70191f10 Reviewed-By: Yagiz Nizipli Reviewed-By: Juan José Arboleda Reviewed-By: Debadree Chatterjee --- tools/v8_gypfiles/features.gypi | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tools/v8_gypfiles/features.gypi b/tools/v8_gypfiles/features.gypi index 7e71e9c46790ab..3a7f355ef8021b 100644 --- a/tools/v8_gypfiles/features.gypi +++ b/tools/v8_gypfiles/features.gypi @@ -72,7 +72,21 @@ 'v8_enable_etw_stack_walking': 1, }, { 'v8_enable_etw_stack_walking': 0, - }] + }], + ['OS=="linux"', { + # Sets -dV8_ENABLE_PRIVATE_MAPPING_FORK_OPTIMIZATION. + # + # This flag speeds up the performance of fork/execve on Linux systems for + # embedders which use it (like Node.js). It works by marking the pages that + # V8 allocates as MADV_DONTFORK. Without MADV_DONTFORK, the Linux kernel + # spends a long time manipulating page mappings on fork and exec which the + # child process doesn't generally need to access. + # + # See v8:7381 for more details. + 'v8_enable_private_mapping_fork_optimization': 1, + }, { + 'v8_enable_private_mapping_fork_optimization': 0, + }], ], 'is_debug%': 0, @@ -320,6 +334,9 @@ ['v8_enable_hugepage==1', { 'defines': ['ENABLE_HUGEPAGE',], }], + ['v8_enable_private_mapping_fork_optimization==1', { + 'defines': ['V8_ENABLE_PRIVATE_MAPPING_FORK_OPTIMIZATION'], + }], ['v8_enable_vtunejit==1', { 'defines': ['ENABLE_VTUNE_JIT_INTERFACE',], }],