Commit be352f7c authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Distribute compilation deadline evenly

Currently, all background compile tasks run for 50ms, then they all
publish their results and restart. This results in significant
contention during the publish phase.
This CL introduces an atomic counter on the {CompilationStateImpl} to
distribute the deadline more evenly: Each task executes between 50ms
and 200ms, and tries to pick a deadline 5ms after the previously
assigned deadline, if this lies within these boundaries. This speeds up
publishing significantly and saves several percent compilation time
overall.

R=mstarzinger@chromium.org

Bug: v8:8916
Change-Id: Id32a5a72c1dd44d30df2ea09643b2a6e4f436944
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1627984
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61841}
parent 7dbbd935
......@@ -440,6 +440,29 @@ class CompilationStateImpl {
return background_compile_token_;
}
double GetCompilationDeadline(double now) {
// Execute for at least 50ms. Try to distribute deadlines of different tasks
// such that every 5ms one task stops. No task should execute longer than
// 200ms though.
constexpr double kMinLimit = 50. / base::Time::kMillisecondsPerSecond;
constexpr double kMaxLimit = 200. / base::Time::kMillisecondsPerSecond;
constexpr double kGapBetweenTasks = 5. / base::Time::kMillisecondsPerSecond;
double min_deadline = now + kMinLimit;
double max_deadline = now + kMaxLimit;
double next_deadline =
next_compilation_deadline_.load(std::memory_order_relaxed);
while (true) {
double deadline =
std::max(min_deadline, std::min(max_deadline, next_deadline));
if (next_compilation_deadline_.compare_exchange_weak(
next_deadline, deadline + kGapBetweenTasks,
std::memory_order_relaxed)) {
return deadline;
}
// Otherwise, retry with the updated {next_deadline}.
}
}
private:
NativeModule* const native_module_;
const std::shared_ptr<BackgroundCompileToken> background_compile_token_;
......@@ -454,6 +477,13 @@ class CompilationStateImpl {
CompilationUnitQueues compilation_unit_queues_;
// Each compilation task executes until a certain deadline. The
// {CompilationStateImpl} orchestrates the deadlines such that they are
// evenly distributed and not all tasks stop at the same time. This removes
// contention during publishing of compilation results and also gives other
// tasks a fair chance to utilize the worker threads on a regular basis.
std::atomic<double> next_compilation_deadline_{0};
// This mutex protects all information of this {CompilationStateImpl} which is
// being accessed concurrently.
mutable base::Mutex mutex_;
......@@ -889,14 +919,11 @@ bool ExecuteCompilationUnits(
if (is_foreground) task_id = 0;
Platform* platform = V8::GetCurrentPlatform();
// Deadline is in 50ms from now.
static constexpr double kBackgroundCompileTimeLimit =
50.0 / base::Time::kMillisecondsPerSecond;
const double deadline =
platform->MonotonicallyIncreasingTime() + kBackgroundCompileTimeLimit;
double compilation_start = platform->MonotonicallyIncreasingTime();
// These fields are initialized in a {BackgroundCompileScope} before
// starting compilation.
double deadline = 0;
base::Optional<CompilationEnv> env;
std::shared_ptr<WireBytesStorage> wire_bytes;
std::shared_ptr<const WasmModule> module;
......@@ -920,12 +947,13 @@ bool ExecuteCompilationUnits(
{
BackgroundCompileScope compile_scope(token);
if (compile_scope.cancelled()) return false;
auto* compilation_state = compile_scope.compilation_state();
deadline = compilation_state->GetCompilationDeadline(compilation_start);
env.emplace(compile_scope.native_module()->CreateCompilationEnv());
wire_bytes = compile_scope.compilation_state()->GetWireBytesStorage();
wire_bytes = compilation_state->GetWireBytesStorage();
module = compile_scope.native_module()->shared_module();
wasm_engine = compile_scope.native_module()->engine();
unit = compile_scope.compilation_state()->GetNextCompilationUnit(
task_id, baseline_only);
unit = compilation_state->GetNextCompilationUnit(task_id, baseline_only);
if (!unit) {
stop(compile_scope);
return false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment