[turboprop] Delay optimizing functions that get hot slower
Functions that get hot quickly are more likely to stay hot and stable, so optimize these functions earlier than the function that become hot slower. To measure how "soon" the function gets hot this cl introduces a global tick that is incremented whenever a function registers a tick. We use the difference in the global tick between the current tick and the last tick on that function to measure how soon the function is becoming hot. We use the last tick to account for functions that aren't used so much at the start but become hot in a later phase. Currently we use this heuristic only for Turboprop tierups. It is possible to extend this to extend this to Turbofan in future. Bug: v8:9684 Change-Id: I8ef265c03520274c68d56a9d35429531a3ba3d1d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2627850 Commit-Queue: Mythri Alle <mythria@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Cr-Commit-Position: refs/heads/master@{#72281}
This commit is contained in:
parent
27485b3535
commit
502419a803
@ -48,6 +48,19 @@ static const int kMaxBytecodeSizeForEarlyOpt = 90;
|
||||
// FLAG_ticks_scale_factor_for_top_tier.
|
||||
static const int kProfilerTicksForTurboPropOSR = 4 * 10;
|
||||
|
||||
// These are used to decide when we tiering up to Turboprop.
|
||||
// The number of ticks required for tiering up to Turboprop is based on how
|
||||
// "soon" the function becomes hot. We use kMidTierGlobalTicksScaleFactor to
|
||||
// scale the difference in global ticks since the last time a function saw a
|
||||
// tick. The scaled difference is used to to increase the number of ticks
|
||||
// required for tiering up to Turboprop.
|
||||
static const int kMidTierGlobalTicksScaleFactor = 100;
|
||||
|
||||
// This is used to limit the number of additional ticks that the
|
||||
// kMidTierGlobalTicksScaleFactor can increase threshold for mid-tier tier
|
||||
// tierup.
|
||||
static const int kMaxAdditionalMidTierGlobalTicks = 10;
|
||||
|
||||
#define OPTIMIZATION_REASON_LIST(V) \
|
||||
V(DoNotOptimize, "do not optimize") \
|
||||
V(HotAndStable, "hot and stable") \
|
||||
@ -121,7 +134,7 @@ void TraceRecompile(JSFunction function, OptimizationReason reason,
|
||||
} // namespace
|
||||
|
||||
RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
|
||||
: isolate_(isolate), any_ic_changed_(false) {}
|
||||
: isolate_(isolate), any_ic_changed_(false), current_global_ticks_(0) {}
|
||||
|
||||
void RuntimeProfiler::Optimize(JSFunction function, OptimizationReason reason,
|
||||
CodeKind code_kind) {
|
||||
@ -192,6 +205,9 @@ void RuntimeProfiler::MaybeOptimizeFrame(JSFunction function,
|
||||
if (reason != OptimizationReason::kDoNotOptimize) {
|
||||
Optimize(function, reason, code_kind);
|
||||
}
|
||||
function.feedback_vector()
|
||||
.set_global_ticks_at_last_runtime_profiler_interrupt(
|
||||
current_global_ticks_);
|
||||
}
|
||||
|
||||
bool RuntimeProfiler::MaybeOSR(JSFunction function, InterpretedFrame* frame) {
|
||||
@ -266,6 +282,17 @@ OptimizationReason RuntimeProfiler::ShouldOptimize(JSFunction function,
|
||||
int ticks_for_optimization =
|
||||
kProfilerTicksBeforeOptimization +
|
||||
(bytecode.length() / kBytecodeSizeAllowancePerTick);
|
||||
if (FLAG_turboprop && !active_tier_is_turboprop) {
|
||||
DCHECK_EQ(function.NextTier(), CodeKind::TURBOPROP);
|
||||
int global_ticks_diff =
|
||||
(current_global_ticks_ -
|
||||
function.feedback_vector()
|
||||
.global_ticks_at_last_runtime_profiler_interrupt());
|
||||
ticks_for_optimization =
|
||||
ticks_for_optimization +
|
||||
std::min(global_ticks_diff / kMidTierGlobalTicksScaleFactor,
|
||||
kMaxAdditionalMidTierGlobalTicks);
|
||||
}
|
||||
ticks_for_optimization *= scale_factor;
|
||||
if (ticks >= ticks_for_optimization) {
|
||||
return OptimizationReason::kHotAndStable;
|
||||
@ -294,6 +321,10 @@ RuntimeProfiler::MarkCandidatesForOptimizationScope::
|
||||
: handle_scope_(profiler->isolate_), profiler_(profiler) {
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
||||
"V8.MarkCandidatesForOptimization");
|
||||
if (profiler_->current_global_ticks_ <
|
||||
FeedbackVector::GlobalTicksAtLastRuntimeProfilerInterruptBits::kMax - 1) {
|
||||
profiler_->current_global_ticks_ += 1;
|
||||
}
|
||||
}
|
||||
|
||||
RuntimeProfiler::MarkCandidatesForOptimizationScope::
|
||||
|
@ -65,6 +65,7 @@ class RuntimeProfiler {
|
||||
|
||||
Isolate* isolate_;
|
||||
bool any_ic_changed_;
|
||||
unsigned int current_global_ticks_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -126,6 +126,16 @@ OptimizationMarker FeedbackVector::optimization_marker() const {
|
||||
return OptimizationMarkerBits::decode(flags());
|
||||
}
|
||||
|
||||
int FeedbackVector::global_ticks_at_last_runtime_profiler_interrupt() const {
|
||||
return GlobalTicksAtLastRuntimeProfilerInterruptBits::decode(flags());
|
||||
}
|
||||
|
||||
void FeedbackVector::set_global_ticks_at_last_runtime_profiler_interrupt(
|
||||
int ticks) {
|
||||
set_flags(
|
||||
GlobalTicksAtLastRuntimeProfilerInterruptBits::update(flags(), ticks));
|
||||
}
|
||||
|
||||
OptimizationTier FeedbackVector::optimization_tier() const {
|
||||
OptimizationTier tier = OptimizationTierBits::decode(flags());
|
||||
// It is possible that the optimization tier bits aren't updated when the code
|
||||
|
@ -217,6 +217,8 @@ class FeedbackVector
|
||||
inline bool has_optimization_marker() const;
|
||||
inline OptimizationMarker optimization_marker() const;
|
||||
inline OptimizationTier optimization_tier() const;
|
||||
inline int global_ticks_at_last_runtime_profiler_interrupt() const;
|
||||
inline void set_global_ticks_at_last_runtime_profiler_interrupt(int ticks);
|
||||
void ClearOptimizedCode();
|
||||
void EvictOptimizedCodeMarkedForDeoptimization(SharedFunctionInfo shared,
|
||||
const char* reason);
|
||||
|
@ -8,6 +8,7 @@ type OptimizationTier extends uint16 constexpr 'OptimizationTier';
|
||||
bitfield struct FeedbackVectorFlags extends uint32 {
|
||||
optimization_marker: OptimizationMarker: 3 bit;
|
||||
optimization_tier: OptimizationTier: 2 bit;
|
||||
global_ticks_at_last_runtime_profiler_interrupt: uint32: 24 bit;
|
||||
}
|
||||
|
||||
@generateBodyDescriptor
|
||||
|
Loading…
Reference in New Issue
Block a user