From a8c55e621f2f60cd6b5e039052768d183449245d Mon Sep 17 00:00:00 2001 From: Aleksandr Emelenko Date: Fri, 19 May 2023 17:38:39 +0300 Subject: [PATCH 1/9] Testing Change-Id: I374d08218930bc0c84d7ae1b8c42895c6bdd966f --- runtime/mem/gc/g1/g1-gc.cpp | 4 ++++ runtime/mem/gc/gc_trigger.cpp | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/runtime/mem/gc/g1/g1-gc.cpp b/runtime/mem/gc/g1/g1-gc.cpp index e1bcc92c5..6d04ab3c6 100644 --- a/runtime/mem/gc/g1/g1-gc.cpp +++ b/runtime/mem/gc/g1/g1-gc.cpp @@ -14,6 +14,7 @@ */ #include "include/mem/panda_string.h" +#include "mem/gc/gc.h" #include "runtime/include/panda_vm.h" #include "runtime/mem/gc/card_table-inl.h" #include "runtime/mem/gc/dynamic/gc_marker_dynamic-inl.h" @@ -809,9 +810,11 @@ bool G1GC::HaveGarbageRegions() // Use GetTopGarbageRegions because it doesn't return current regions PandaVector regions = GetG1ObjectAllocator()->template GetTopGarbageRegions(1U); if (regions.empty()) { + LOG_INFO_GC << "HaveGarbageRegions, region vector is empty"; return false; } double garbage_rate = static_cast(regions[0]->GetGarbageBytes()) / regions[0]->Size(); + LOG_INFO_GC << "HaveGarbageRegions, garbage rate is " << garbage_rate << ", compare to options " << region_garbage_rate_threshold_; return garbage_rate >= region_garbage_rate_threshold_; } @@ -1293,6 +1296,7 @@ void G1GC::ConcurrentMarking(panda::GCTask &task) CollectNonRegularObjects(task); } } else { + LOG_INFO_GC << "Concurrent collection has been interrupted"; concurrent_marking_stack_.Clear(); ClearSatb(); } diff --git a/runtime/mem/gc/gc_trigger.cpp b/runtime/mem/gc/gc_trigger.cpp index 502037cb1..1a7308041 100644 --- a/runtime/mem/gc/gc_trigger.cpp +++ b/runtime/mem/gc/gc_trigger.cpp @@ -91,6 +91,7 @@ void GCTriggerHeap::ComputeNewTargetFootprint(const GCTask &task, size_t heap_si GC *gc = Thread::GetCurrent()->GetVM()->GetGC(); if (gc->IsGenerational() && task.reason == GCTaskCause::YOUNG_GC_CAUSE && task.collection_type != GCCollectionType::MIXED) { + LOG(DEBUG, GC) << "ComputeNewTargetFootprint: skip update"; // we don't want to update heap-trigger on young-gc return; } @@ -101,7 +102,7 @@ void GCTriggerHeap::ComputeNewTargetFootprint(const GCTask &task, size_t heap_si // constraints imposed on other reads or writes target_footprint_.store(target, std::memory_order_relaxed); - LOG(DEBUG, GC_TRIGGER) << "ComputeNewTargetFootprint target_footprint = " << target; + LOG(DEBUG, GC) << "ComputeNewTargetFootprint target_footprint = " << target; } size_t GCTriggerHeap::ComputeTarget(size_t heap_size_before_gc, size_t heap_size) -- Gitee From d1a36c7579b125972e096e655b7e96112337fd7c Mon Sep 17 00:00:00 2001 From: Aleksandr Emelenko Date: Sat, 20 May 2023 15:59:51 +0300 Subject: [PATCH 2/9] Remove interrupt concurrent marking Signed-off-by: Aleksandr Emelenko --- runtime/mem/gc/g1/g1-gc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/mem/gc/g1/g1-gc.cpp b/runtime/mem/gc/g1/g1-gc.cpp index 6d04ab3c6..af1137053 100644 --- a/runtime/mem/gc/g1/g1-gc.cpp +++ b/runtime/mem/gc/g1/g1-gc.cpp @@ -1891,7 +1891,7 @@ template void G1GC::OnWaitForIdleFail() { if (this->GetGCPhase() == GCPhase::GC_PHASE_MARK) { - interrupt_concurrent_flag_ = true; + // interrupt_concurrent_flag_ = true; if (this->GetSettings()->G1EnablePauseTimeGoal()) { os::memory::LockHolder lh(concurrent_mark_mutex_); concurrent_mark_cond_var_.Signal(); -- Gitee From 15f00a8ef39d8df871c5897c24bc2a3520f6d4f4 Mon Sep 17 00:00:00 2001 From: Aleksandr Emelenko Date: Mon, 22 May 2023 19:44:58 +0300 Subject: [PATCH 3/9] Created using gc workers during concurrent marking Signed-off-by: Aleksandr Emelenko Change-Id: I840110c949036b5e48704722fb56029c723e6a46 --- runtime/mem/gc/g1/g1-gc.cpp | 24 ++++++++++++++++++++++- runtime/mem/gc/g1/g1-gc.cpp.rej | 14 +++++++++++++ runtime/mem/gc/gc_adaptive_stack.cpp | 9 +++++++++ runtime/mem/gc/gc_adaptive_stack.h | 8 ++++++++ runtime/mem/gc/gc_workers_thread_pool.h | 3 ++- runtime/mem/gc/generational-gc-base-inl.h | 6 +++++- 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 runtime/mem/gc/g1/g1-gc.cpp.rej diff --git a/runtime/mem/gc/g1/g1-gc.cpp b/runtime/mem/gc/g1/g1-gc.cpp index af1137053..268fc107a 100644 --- a/runtime/mem/gc/g1/g1-gc.cpp +++ b/runtime/mem/gc/g1/g1-gc.cpp @@ -533,6 +533,19 @@ void G1GC::WorkerTaskProcessing(GCWorkersTask *task, [[maybe_unu this->GetInternalAllocator()->Delete(objects_stack); break; } + case GCWorkersTaskTypes::TASK_CONCURRENT_MARK: { + const ReferenceCheckPredicateT &disable_ref_pred = []([[maybe_unused]] const ObjectHeader *obj) { + return false; + }; + auto objects_stack = task->GetMarkingStack(); + auto interrupt_checker = [this, &objects_stack]() { + return !objects_stack->Empty() && !interrupt_concurrent_flag_; + }; + this->MarkStackCond(&marker_, objects_stack, interrupt_checker, disable_ref_pred, GC::EmptyReferenceProcessPredicate); + ASSERT(objects_stack->Empty()); + this->GetInternalAllocator()->Delete(objects_stack); + break; + } case GCWorkersTaskTypes::TASK_REGION_COMPACTING: { auto data = task->GetRegionData(); PandaVector *moved_objects = data->first; @@ -1250,6 +1263,15 @@ void G1GC::FullMarking(panda::GCTask &task) template void G1GC::ConcurrentMarking(panda::GCTask &task) { + static bool concurrent_marking_interrupted = false; + if (concurrent_marking_interrupted) { + bool use_gc_workers = this->GetSettings()->ParallelMarkingEnabled(); + concurrent_marking_stack_.ChangeLimits(use_gc_workers ? this->GetSettings()->GCRootMarkingStackMaxSize() : 0, + use_gc_workers ? this->GetSettings()->GCWorkersMarkingStackMaxSize() : 0, + GCWorkersTaskTypes::TASK_CONCURRENT_MARK, + this->GetSettings()->GCMarkingStackNewTasksFrequency()); + } + GCScope scoped_func(__FUNCTION__, this, GCPhase::GC_PHASE_MARK); { PauseTimeGoalDelay(); // initial mark is always separate pause with pause-time-goal GC trigger @@ -1891,7 +1913,7 @@ template void G1GC::OnWaitForIdleFail() { if (this->GetGCPhase() == GCPhase::GC_PHASE_MARK) { - // interrupt_concurrent_flag_ = true; + interrupt_concurrent_flag_ = true; if (this->GetSettings()->G1EnablePauseTimeGoal()) { os::memory::LockHolder lh(concurrent_mark_mutex_); concurrent_mark_cond_var_.Signal(); diff --git a/runtime/mem/gc/g1/g1-gc.cpp.rej b/runtime/mem/gc/g1/g1-gc.cpp.rej new file mode 100644 index 000000000..aab60acee --- /dev/null +++ b/runtime/mem/gc/g1/g1-gc.cpp.rej @@ -0,0 +1,14 @@ +diff a/runtime/mem/gc/g1/g1-gc.cpp b/runtime/mem/gc/g1/g1-gc.cpp (rejected hunks) +@@ -1274,9 +1296,12 @@ void G1GC::ConcurrentMarking(panda::GCTask &task) + ConcurrentScope concurrent_scope(this); + CollectNonRegularObjects(task); + } ++ concurrent_marking_interrupted = false; ++ concurrent_marking_stack_.ChangeLimits(); + } else { + concurrent_marking_stack_.Clear(); + ClearSatb(); ++ concurrent_marking_interrupted = true; + } + ASSERT(concurrent_marking_stack_.Empty()); + } diff --git a/runtime/mem/gc/gc_adaptive_stack.cpp b/runtime/mem/gc/gc_adaptive_stack.cpp index 3378439b3..021257bde 100644 --- a/runtime/mem/gc/gc_adaptive_stack.cpp +++ b/runtime/mem/gc/gc_adaptive_stack.cpp @@ -164,4 +164,13 @@ void GCAdaptiveStack::Clear() *stack_dst_ = PandaStack(); } +void GCAdaptiveStack::ChangeLimits(size_t stack_size_limit, size_t new_task_stack_size_limit, GCWorkersTaskTypes task, + uint64_t time_limit_for_new_task_creation) +{ + stack_size_limit_ = stack_size_limit; + new_task_stack_size_limit_ = new_task_stack_size_limit; + time_limit_for_new_task_creation_ = time_limit_for_new_task_creation; + task_type_ = task; +} + } // namespace panda::mem diff --git a/runtime/mem/gc/gc_adaptive_stack.h b/runtime/mem/gc/gc_adaptive_stack.h index d32333c5e..1a2fa41e1 100644 --- a/runtime/mem/gc/gc_adaptive_stack.h +++ b/runtime/mem/gc/gc_adaptive_stack.h @@ -27,6 +27,7 @@ enum class GCWorkersTaskTypes { TASK_MARKING, TASK_REMARK, TASK_FULL_MARK, + TASK_CONCURRENT_MARK, TASK_REGION_COMPACTING, TASK_ROOT_COLLECTION, TASK_MOVE_YOUNG_ALIVE_OBJECTS, @@ -97,6 +98,13 @@ public: */ void Clear(); + /** + * \brief Change stack limits + */ + void ChangeLimits(size_t stack_size_limit = 0, size_t new_task_stack_size_limit = 0, + GCWorkersTaskTypes task = GCWorkersTaskTypes::TASK_EMPTY, + uint64_t time_limit_for_new_task_creation = 0); + private: static constexpr size_t DEFAULT_TASKS_FOR_TIME_CHECK = 10; diff --git a/runtime/mem/gc/gc_workers_thread_pool.h b/runtime/mem/gc/gc_workers_thread_pool.h index b68ec76b4..aac9d3061 100644 --- a/runtime/mem/gc/gc_workers_thread_pool.h +++ b/runtime/mem/gc/gc_workers_thread_pool.h @@ -105,7 +105,7 @@ public: explicit GCWorkersTask(GCWorkersTaskTypes type, StackType *marking_stack) : task_type_(type) { ASSERT(type == GCWorkersTaskTypes::TASK_MARKING || type == GCWorkersTaskTypes::TASK_REMARK || - type == GCWorkersTaskTypes::TASK_FULL_MARK); + type == GCWorkersTaskTypes::TASK_CONCURRENT_MARK || type == GCWorkersTaskTypes::TASK_FULL_MARK); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access) storage_.marking_stack = marking_stack; } @@ -130,6 +130,7 @@ public: StackType *GetMarkingStack() const { ASSERT(task_type_ == GCWorkersTaskTypes::TASK_MARKING || task_type_ == GCWorkersTaskTypes::TASK_REMARK || + task_type_ == GCWorkersTaskTypes::TASK_CONCURRENT_MARK || task_type_ == GCWorkersTaskTypes::TASK_FULL_MARK); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access) return storage_.marking_stack; diff --git a/runtime/mem/gc/generational-gc-base-inl.h b/runtime/mem/gc/generational-gc-base-inl.h index e71e00f86..7828bf871 100644 --- a/runtime/mem/gc/generational-gc-base-inl.h +++ b/runtime/mem/gc/generational-gc-base-inl.h @@ -65,7 +65,11 @@ NO_THREAD_SAFETY_ANALYSIS void GenerationalGC::ConcurrentMark(Ma { GCScope scoped_func(__FUNCTION__, this, GCPhase::GC_PHASE_MARK); ConcurrentScope concurrent_scope(this); - MarkImpl(marker, objects_stack, visit_card_table_roots, pred, ref_pred, mem_range_checker); + MarkImpl(marker, objects_stack, visit_card_table_roots, pred, ref_pred, + mem_range_checker); // CODECHECK-NOLINT(C_RULE_ID_INDENT_CHECK) + if (this->GetSettings()->ParallelMarkingEnabled() && this->GetType() == GCType::G1_GC) { + this->GetWorkersPool()->WaitUntilTasksEnd(); + } } template -- Gitee From 8cae50ec0369bd497fc2fbcc6df216802ce6f21b Mon Sep 17 00:00:00 2001 From: Aleksandr Emelenko Date: Wed, 24 May 2023 12:38:21 +0300 Subject: [PATCH 4/9] Reserve memory for moved objects in RegionCompactingImpl Change-Id: I0cf0f7ed3acecbbce876c7b17f4c70dea6e594cc Signed-off-by: Aleksandr Emelenko --- runtime/mem/gc/g1/g1-gc.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/mem/gc/g1/g1-gc.cpp b/runtime/mem/gc/g1/g1-gc.cpp index 268fc107a..e1c0c5f83 100644 --- a/runtime/mem/gc/g1/g1-gc.cpp +++ b/runtime/mem/gc/g1/g1-gc.cpp @@ -192,6 +192,7 @@ void G1GC::DoRegionCompacting(Region *region, bool use_gc_worker auto internal_allocator = this->GetInternalAllocator(); if (use_gc_workers) { auto vector = internal_allocator->template New>(); + vector->reserve(9000); moved_objects_vector->push_back(vector); auto storage = internal_allocator->template New(vector, region); if (!this->GetWorkersPool()->AddTask(GCWorkersTaskTypes::TASK_REGION_COMPACTING, storage)) { -- Gitee From 3376e50e93594cac4e747b8bed3005fa1ddb43ce Mon Sep 17 00:00:00 2001 From: Aleksandr Emelenko Date: Wed, 24 May 2023 15:17:19 +0300 Subject: [PATCH 5/9] Do not set affinity for concurrent marking Change-Id: I9596235e1b739a5f8abad69e72269b12bb06e4a8 Signed-off-by: Aleksandr Emelenko --- runtime/mem/gc/g1/g1-gc.cpp | 3 ++- runtime/mem/gc/gc.cpp | 10 ++++++---- runtime/mem/gc/gc.h | 4 ++-- runtime/mem/gc/gen-gc/gen-gc.cpp | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/runtime/mem/gc/g1/g1-gc.cpp b/runtime/mem/gc/g1/g1-gc.cpp index e1c0c5f83..d210a4844 100644 --- a/runtime/mem/gc/g1/g1-gc.cpp +++ b/runtime/mem/gc/g1/g1-gc.cpp @@ -1391,10 +1391,11 @@ void G1GC::ConcurrentMark(Marker *marker, GCMarkingStackType *ob const ReferenceCheckPredicateT &ref_pred, const MemRangeChecker &mem_range_checker) { - ConcurrentScope concurrent_scope(this); + ConcurrentScope concurrent_scope(this, true, false); GCScope scope(__FUNCTION__, this, GCPhase::GC_PHASE_MARK); this->MarkImpl(marker, objects_stack, visit_card_table_roots, pred, ref_pred, mem_range_checker); if (interrupt_concurrent_flag_) { + LOG_INFO_GC << "Interrupted during marking"; return; } CalcLiveBytesForMovableTenuredRegions(); diff --git a/runtime/mem/gc/gc.cpp b/runtime/mem/gc/gc.cpp index 6ddc986aa..88912c5eb 100644 --- a/runtime/mem/gc/gc.cpp +++ b/runtime/mem/gc/gc.cpp @@ -720,12 +720,12 @@ void GC::PrintDetailedLog() LOG(INFO, GC) << this->GetTiming()->Dump(); } -ConcurrentScope::ConcurrentScope(GC *gc, bool auto_start) +ConcurrentScope::ConcurrentScope(GC *gc, bool auto_start, bool slower_affinity) { LOG(DEBUG, GC) << "Start ConcurrentScope"; gc_ = gc; if (auto_start) { - Start(); + Start(slower_affinity); } } @@ -738,10 +738,12 @@ ConcurrentScope::~ConcurrentScope() } } -NO_THREAD_SAFETY_ANALYSIS void ConcurrentScope::Start() +NO_THREAD_SAFETY_ANALYSIS void ConcurrentScope::Start(bool slower_affinity) { - if (!started_ && gc_->IsConcurrencyAllowed()) { + if (gc_->IsConcurrencyAllowed() && slower_affinity) { gc_->SetupCpuAffinityBeforeConcurrent(); + } + if (!started_) { gc_->GetPandaVm()->GetRendezvous()->SafepointEnd(); started_ = true; } diff --git a/runtime/mem/gc/gc.h b/runtime/mem/gc/gc.h index ab88d1fc7..ab00b3027 100644 --- a/runtime/mem/gc/gc.h +++ b/runtime/mem/gc/gc.h @@ -816,11 +816,11 @@ GC *CreateGC(GCType gc_type, ObjectAllocatorBase *object_allocator, const GCSett */ class ConcurrentScope final { public: - explicit ConcurrentScope(GC *gc, bool auto_start = true); + explicit ConcurrentScope(GC *gc, bool auto_start = true, bool slower_affinity = true); NO_COPY_SEMANTIC(ConcurrentScope); NO_MOVE_SEMANTIC(ConcurrentScope); ~ConcurrentScope(); - void Start(); + void Start(bool slower_affinity); private: GC *gc_; diff --git a/runtime/mem/gc/gen-gc/gen-gc.cpp b/runtime/mem/gc/gen-gc/gen-gc.cpp index cdb4ab0c1..aa01c3ae0 100644 --- a/runtime/mem/gc/gen-gc/gen-gc.cpp +++ b/runtime/mem/gc/gen-gc/gen-gc.cpp @@ -612,7 +612,7 @@ NO_THREAD_SAFETY_ANALYSIS void GenGC::Sweep() }); // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon) if constexpr (CONCURRENT) { - concurrent_scope.Start(); // enable concurrent after GC_PHASE_SWEEP has been set + concurrent_scope.Start(true); // enable concurrent after GC_PHASE_SWEEP has been set } // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon) -- Gitee From c657e7baeefd4c0e2adaf029333c693d579dc1cb Mon Sep 17 00:00:00 2001 From: Aleksandr Emelenko Date: Thu, 25 May 2023 18:26:25 +0300 Subject: [PATCH 6/9] Added affinity logs Change-Id: I9b05a7dcc03ab2080f20f1a617d7822be2478fd3 Signed-off-by: Aleksandr Emelenko --- platforms/unix/libpandabase/cpu_affinity.cpp | 10 ++++++++++ runtime/mem/gc/gc.cpp | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/platforms/unix/libpandabase/cpu_affinity.cpp b/platforms/unix/libpandabase/cpu_affinity.cpp index 3c1abb903..b8c3971f1 100644 --- a/platforms/unix/libpandabase/cpu_affinity.cpp +++ b/platforms/unix/libpandabase/cpu_affinity.cpp @@ -212,6 +212,9 @@ void CpuAffinityManager::LoadCpuFreq() ASSERT(!best_cpu_set_.IsEmpty()); ASSERT(!middle_cpu_set_.IsEmpty()); ASSERT(!weak_cpu_set_.IsEmpty()); + LOG(INFO, GC) << "LoadCpuFreq: \n best " << os::CpuAffinityManager::CpuSetToString(best_cpu_set_); + LOG(INFO, GC) << " middle " << os::CpuAffinityManager::CpuSetToString(middle_cpu_set_); + LOG(INFO, GC) << " weak " << os::CpuAffinityManager::CpuSetToString(weak_cpu_set_); CpuSet::Or(best_and_middle_cpu_set_, best_cpu_set_, middle_cpu_set_); ASSERT(!best_and_middle_cpu_set_.IsEmpty()); for (auto it : cpu) { @@ -246,6 +249,13 @@ bool CpuAffinityManager::SetAffinityForThread(int tid, const CpuSet &cpuset) LOG_IF(!success, DEBUG, COMMON) << "Couldn't set affinity with mask " << CpuSetToString(cpuset) << " for thread with tid = " << (tid != 0 ? tid : thread::GetCurrentThreadId()) << ", error: " << std::strerror(errno); + os::CpuSet local_set; + os::CpuAffinityManager::GetCurrentThreadAffinity(local_set); + if (tid == 0) { + LOG(INFO, GC) << "Affinity: \n main thread = " << os::CpuAffinityManager::CpuSetToString(local_set); + } else { + LOG(INFO, GC) << " worker = " << os::CpuAffinityManager::CpuSetToString(local_set); + } return success; } diff --git a/runtime/mem/gc/gc.cpp b/runtime/mem/gc/gc.cpp index 88912c5eb..077185dd7 100644 --- a/runtime/mem/gc/gc.cpp +++ b/runtime/mem/gc/gc.cpp @@ -195,6 +195,7 @@ void GC::SetupCpuAffinity() // secondly try to use best + middle CPUs mask if (!os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST) && !os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST | os::CpuPower::MIDDLE)) { + LOG(INFO, GC) << "SetAffinityForCurrentThread for the main thread failed"; affinity_before_gc_.Clear(); } // Some GCs don't use GC Workers @@ -211,7 +212,9 @@ void GC::SetupCpuAffinityAfterConcurrent() // Try to set GC Thread on best CPUs after concurrent if (!os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST)) { // If it failed for only best CPUs then try to use best + middle CPUs mask after concurrent - os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST | os::CpuPower::MIDDLE); + if (!os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST | os::CpuPower::MIDDLE)) { + LOG(INFO, GC) << "SetupCpuAffinityAfterConcurrent for the main thread failed"; + } } // Some GCs don't use GC Workers if (workers_pool_ != nullptr) { -- Gitee From 8dfee7db93ded40809263dca2071289682463250 Mon Sep 17 00:00:00 2001 From: Aleksandr Emelenko Date: Mon, 29 May 2023 18:05:14 +0300 Subject: [PATCH 7/9] Fix affinity Change-Id: Ia7abe4c17343dbaa732fb0f41ba4a803e7aeb2d6 Signed-off-by: Aleksandr Emelenko --- platforms/unix/libpandabase/cpu_affinity.cpp | 2 +- runtime/mem/gc/gc.cpp | 5 ++++- runtime/mem/gc/gc.h | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/platforms/unix/libpandabase/cpu_affinity.cpp b/platforms/unix/libpandabase/cpu_affinity.cpp index b8c3971f1..cc59aed9b 100644 --- a/platforms/unix/libpandabase/cpu_affinity.cpp +++ b/platforms/unix/libpandabase/cpu_affinity.cpp @@ -250,7 +250,7 @@ bool CpuAffinityManager::SetAffinityForThread(int tid, const CpuSet &cpuset) << " for thread with tid = " << (tid != 0 ? tid : thread::GetCurrentThreadId()) << ", error: " << std::strerror(errno); os::CpuSet local_set; - os::CpuAffinityManager::GetCurrentThreadAffinity(local_set); + os::CpuAffinityManager::GetThreadAffinity(tid, local_set); if (tid == 0) { LOG(INFO, GC) << "Affinity: \n main thread = " << os::CpuAffinityManager::CpuSetToString(local_set); } else { diff --git a/runtime/mem/gc/gc.cpp b/runtime/mem/gc/gc.cpp index 077185dd7..1caafabb1 100644 --- a/runtime/mem/gc/gc.cpp +++ b/runtime/mem/gc/gc.cpp @@ -725,6 +725,7 @@ void GC::PrintDetailedLog() ConcurrentScope::ConcurrentScope(GC *gc, bool auto_start, bool slower_affinity) { + slower_affinity_ = slower_affinity; LOG(DEBUG, GC) << "Start ConcurrentScope"; gc_ = gc; if (auto_start) { @@ -735,8 +736,10 @@ ConcurrentScope::ConcurrentScope(GC *gc, bool auto_start, bool slower_affinity) ConcurrentScope::~ConcurrentScope() { LOG(DEBUG, GC) << "Stop ConcurrentScope"; - if (started_ && gc_->IsConcurrencyAllowed()) { + if (started_) { gc_->GetPandaVm()->GetRendezvous()->SafepointBegin(); + } + if (gc_->IsConcurrencyAllowed() && slower_affinity_) { gc_->SetupCpuAffinityAfterConcurrent(); } } diff --git a/runtime/mem/gc/gc.h b/runtime/mem/gc/gc.h index ab00b3027..e6985796e 100644 --- a/runtime/mem/gc/gc.h +++ b/runtime/mem/gc/gc.h @@ -825,6 +825,7 @@ public: private: GC *gc_; bool started_ = false; + bool slower_affinity_ = true; }; } // namespace panda::mem -- Gitee From 7e612dab7dc8beaaada0270545644b15ea33b1eb Mon Sep 17 00:00:00 2001 From: Aleksandr Emelenko Date: Tue, 30 May 2023 15:26:26 +0300 Subject: [PATCH 8/9] Added new task scope Change-Id: Iad5d38ea2f688895d8aed0b86dfa0f9915287037 Signed-off-by: Aleksandr Emelenko --- runtime/mem/gc/g1/g1-gc.cpp | 8 +++++--- runtime/mem/gc/gc_workers_thread_pool.cpp | 8 ++++++++ runtime/thread_pool.h | 4 ++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/runtime/mem/gc/g1/g1-gc.cpp b/runtime/mem/gc/g1/g1-gc.cpp index d210a4844..0b60fb87a 100644 --- a/runtime/mem/gc/g1/g1-gc.cpp +++ b/runtime/mem/gc/g1/g1-gc.cpp @@ -192,7 +192,6 @@ void G1GC::DoRegionCompacting(Region *region, bool use_gc_worker auto internal_allocator = this->GetInternalAllocator(); if (use_gc_workers) { auto vector = internal_allocator->template New>(); - vector->reserve(9000); moved_objects_vector->push_back(vector); auto storage = internal_allocator->template New(vector, region); if (!this->GetWorkersPool()->AddTask(GCWorkersTaskTypes::TASK_REGION_COMPACTING, storage)) { @@ -415,6 +414,7 @@ template template void G1GC::RegionCompactingImpl(PandaVector *moved_objects, Region *region) { + ScopedRegionCollectionInfo region_compacting_info(this, "RegionCompactingImpl", region, true, 0); auto object_allocator = this->GetG1ObjectAllocator(); size_t move_size = 0; size_t move_count = 0; @@ -542,7 +542,8 @@ void G1GC::WorkerTaskProcessing(GCWorkersTask *task, [[maybe_unu auto interrupt_checker = [this, &objects_stack]() { return !objects_stack->Empty() && !interrupt_concurrent_flag_; }; - this->MarkStackCond(&marker_, objects_stack, interrupt_checker, disable_ref_pred, GC::EmptyReferenceProcessPredicate); + this->MarkStackCond(&marker_, objects_stack, interrupt_checker, disable_ref_pred, + GC::EmptyReferenceProcessPredicate); ASSERT(objects_stack->Empty()); this->GetInternalAllocator()->Delete(objects_stack); break; @@ -828,7 +829,8 @@ bool G1GC::HaveGarbageRegions() return false; } double garbage_rate = static_cast(regions[0]->GetGarbageBytes()) / regions[0]->Size(); - LOG_INFO_GC << "HaveGarbageRegions, garbage rate is " << garbage_rate << ", compare to options " << region_garbage_rate_threshold_; + LOG_INFO_GC << "HaveGarbageRegions, garbage rate is " << garbage_rate << ", compare to options " + << region_garbage_rate_threshold_; return garbage_rate >= region_garbage_rate_threshold_; } diff --git a/runtime/mem/gc/gc_workers_thread_pool.cpp b/runtime/mem/gc/gc_workers_thread_pool.cpp index 460347fc5..362898913 100644 --- a/runtime/mem/gc/gc_workers_thread_pool.cpp +++ b/runtime/mem/gc/gc_workers_thread_pool.cpp @@ -89,15 +89,23 @@ GCWorkersThreadPool::~GCWorkersThreadPool() void GCWorkersThreadPool::WaitUntilTasksEnd() { + uint64_t start_helping = time::GetCurrentTimeInNanos(); thread_pool_->Help(); + uint64_t start_waiting = time::GetCurrentTimeInNanos(); + LOG(INFO, GC) << "Finished processing task queue, helping consumes " + << Timing::PrettyTimeNs(start_waiting - start_helping); for (;;) { os::memory::LockHolder lock(cond_var_lock_); if (GetSolvedTasks() == GetSendedTasks()) { break; } + LOG(INFO, GC) << "Check condition, unsuccessfull, time spent " + << Timing::PrettyTimeNs(time::GetCurrentTimeInNanos() - start_waiting); cond_var_.TimedWait(&cond_var_lock_, ALL_TASK_FINISH_WAIT_TIMEOUT); } ResetTasks(); + uint64_t end_waiting = time::GetCurrentTimeInNanos(); + LOG(INFO, GC) << "Waited for task end for " << Timing::PrettyTimeNs(end_waiting - start_waiting); } } // namespace panda::mem diff --git a/runtime/thread_pool.h b/runtime/thread_pool.h index f32b0cfa0..59ebe0cd1 100644 --- a/runtime/thread_pool.h +++ b/runtime/thread_pool.h @@ -271,7 +271,11 @@ public: } thread_pool->SignalTask(); LOG(DEBUG, RUNTIME) << "Worker " << i << " started to process task"; + uint64_t start = time::GetCurrentTimeInNanos(); + LOG(INFO, GC) << "Worker " << i << " started to process task"; proc->Process(std::move(task)); + uint64_t end = time::GetCurrentTimeInNanos(); + LOG(INFO, GC) << "Finished processing task Worker " << i << ", spent " << Timing::PrettyTimeNs(end - start); } if (!proc->Destroy()) { LOG(FATAL, RUNTIME) << "Cannot destroy worker thread"; -- Gitee From b3d76f48016e7afaffa7fe3e8570c06cef3ed882 Mon Sep 17 00:00:00 2001 From: Aleksandr Emelenko Date: Wed, 31 May 2023 18:20:20 +0300 Subject: [PATCH 9/9] Changed task wait time Change-Id: I1b066fee8647d166386ab38bc224bae8ce392a23 Signed-off-by: Aleksandr Emelenko --- libpandabase/os/cpu_affinity.h | 4 ++++ platforms/unix/libpandabase/cpu_affinity.cpp | 7 +++++++ platforms/windows/libpandabase/cpu_affinity.cpp | 2 ++ runtime/mem/gc/g1/g1-gc.cpp | 13 ++++++++++--- runtime/mem/gc/g1/update_remset_thread.cpp | 1 + runtime/mem/gc/g1/update_remset_thread.h | 2 +- runtime/mem/gc/gc_workers_thread_pool.cpp | 16 +++++++++++----- runtime/mem/gc/gc_workers_thread_pool.h | 1 + 8 files changed, 37 insertions(+), 9 deletions(-) diff --git a/libpandabase/os/cpu_affinity.h b/libpandabase/os/cpu_affinity.h index 0c7b6f312..b6d9062fb 100644 --- a/libpandabase/os/cpu_affinity.h +++ b/libpandabase/os/cpu_affinity.h @@ -161,6 +161,8 @@ public: return best_and_middle_cpu_set_; } + PANDA_PUBLIC_API static void PringCurrentAffinity(); + /** * Get cpu affinity for current thread * @param tid thread id for getting @@ -176,6 +178,8 @@ public: */ PANDA_PUBLIC_API static bool GetCurrentThreadAffinity(CpuSet &cpuset); + + /** * Get string representation for cpu-set * @tparam StringType type of result string diff --git a/platforms/unix/libpandabase/cpu_affinity.cpp b/platforms/unix/libpandabase/cpu_affinity.cpp index cc59aed9b..62f5e4356 100644 --- a/platforms/unix/libpandabase/cpu_affinity.cpp +++ b/platforms/unix/libpandabase/cpu_affinity.cpp @@ -155,6 +155,13 @@ void CpuAffinityManager::Finalize() weak_cpu_set_.Clear(); } +void CpuAffinityManager::PringCurrentAffinity() +{ + os::CpuSet main_thread_affinity {}; + os::CpuAffinityManager::GetCurrentThreadAffinity(main_thread_affinity); + LOG(INFO, GC) << "Main thread current affinity " << os::CpuAffinityManager::CpuSetToString(main_thread_affinity); +} + /* static */ void CpuAffinityManager::LoadCpuFreq() { diff --git a/platforms/windows/libpandabase/cpu_affinity.cpp b/platforms/windows/libpandabase/cpu_affinity.cpp index 59c218f82..f59b88734 100644 --- a/platforms/windows/libpandabase/cpu_affinity.cpp +++ b/platforms/windows/libpandabase/cpu_affinity.cpp @@ -159,6 +159,8 @@ void CpuAffinityManager::Finalize() weak_cpu_set_.Clear(); } +void CpuAffinityManager::PringCurrentAffinity() {} + /* static */ void CpuAffinityManager::LoadCpuFreq() { diff --git a/runtime/mem/gc/g1/g1-gc.cpp b/runtime/mem/gc/g1/g1-gc.cpp index 0b60fb87a..c6d7e7cef 100644 --- a/runtime/mem/gc/g1/g1-gc.cpp +++ b/runtime/mem/gc/g1/g1-gc.cpp @@ -1797,10 +1797,16 @@ MemRange G1GC::CacheRefsFromRemsets() // some cross region refs might be not processed return false; }; - for (auto region : collection_set_) { - region->GetRemSet()->Iterate(RemsetRegionPredicate, visitor); + { + ScopedTiming t1("Iterate over remset in collection set", *this->GetTiming()); + for (auto region : collection_set_) { + region->GetRemSet()->Iterate(RemsetRegionPredicate, visitor); + } + } + { + ScopedTiming t1("Cache refs from durty cards", *this->GetTiming()); + CacheRefsFromDirtyCards(visitor); } - CacheRefsFromDirtyCards(visitor); #ifndef NDEBUG unique_cards_initialized_ = true; #endif // NDEBUG @@ -1816,6 +1822,7 @@ void G1GC::CacheRefsFromDirtyCards(Visitor visitor) { auto card_table = this->GetCardTable(); constexpr size_t MEM_SIZE = DEFAULT_REGION_SIZE / RemSet<>::Bitmap::GetNumBits(); + LOG(INFO, GC) << "Dirty cards size " << dirty_cards_.size(); for (auto it = dirty_cards_.cbegin(); it != dirty_cards_.cend();) { auto range = card_table->GetMemoryRange(*it); auto addr = range.GetStartAddress(); diff --git a/runtime/mem/gc/g1/update_remset_thread.cpp b/runtime/mem/gc/g1/update_remset_thread.cpp index d3aea7d5f..f71bd725d 100644 --- a/runtime/mem/gc/g1/update_remset_thread.cpp +++ b/runtime/mem/gc/g1/update_remset_thread.cpp @@ -185,6 +185,7 @@ void UpdateRemsetThread::ThreadLoop() auto phase = gc_->GetGCPhase(); if (phase != GCPhase::GC_PHASE_IDLE) { // means GC is in progress now and we need to process more aggressively + thread_cond_var_.Wait(&loop_lock_); continue; } else if (processed_cards < min_concurrent_cards_to_process_) { // NOLINT(readability-else-after-return) Sleep(); diff --git a/runtime/mem/gc/g1/update_remset_thread.h b/runtime/mem/gc/g1/update_remset_thread.h index 748616000..540b7ab23 100644 --- a/runtime/mem/gc/g1/update_remset_thread.h +++ b/runtime/mem/gc/g1/update_remset_thread.h @@ -158,7 +158,7 @@ private: void Sleep() { - static constexpr uint64_t SLEEP_MS = 1; + static constexpr uint64_t SLEEP_MS = 10; thread_cond_var_.TimedWait(&loop_lock_, SLEEP_MS); } diff --git a/runtime/mem/gc/gc_workers_thread_pool.cpp b/runtime/mem/gc/gc_workers_thread_pool.cpp index 362898913..4fa42a451 100644 --- a/runtime/mem/gc/gc_workers_thread_pool.cpp +++ b/runtime/mem/gc/gc_workers_thread_pool.cpp @@ -15,10 +15,10 @@ #include -#include "os/cpu_affinity.h" #include "runtime/mem/gc/gc.h" #include "runtime/mem/gc/gc_workers_thread_pool.h" #include "runtime/mem/region_space.h" +#include "libpandabase/os/cpu_affinity.h" namespace panda::mem { @@ -92,20 +92,26 @@ void GCWorkersThreadPool::WaitUntilTasksEnd() uint64_t start_helping = time::GetCurrentTimeInNanos(); thread_pool_->Help(); uint64_t start_waiting = time::GetCurrentTimeInNanos(); - LOG(INFO, GC) << "Finished processing task queue, helping consumes " + LOG(INFO, GC) << time::GetCurrentTimeString() << "Finished processing task queue, helping consumes " << Timing::PrettyTimeNs(start_waiting - start_helping); + os::CpuAffinityManager::PringCurrentAffinity(); + for (;;) { os::memory::LockHolder lock(cond_var_lock_); if (GetSolvedTasks() == GetSendedTasks()) { break; } - LOG(INFO, GC) << "Check condition, unsuccessfull, time spent " + LOG(INFO, GC) << time::GetCurrentTimeString() << "Check condition, unsuccessfull, time spent " << Timing::PrettyTimeNs(time::GetCurrentTimeInNanos() - start_waiting); - cond_var_.TimedWait(&cond_var_lock_, ALL_TASK_FINISH_WAIT_TIMEOUT); + os::CpuAffinityManager::PringCurrentAffinity(); + os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST); + cond_var_.TimedWait(&cond_var_lock_, 0, ALL_TASK_FINISH_WAIT_TIMEOUT, true); } ResetTasks(); uint64_t end_waiting = time::GetCurrentTimeInNanos(); - LOG(INFO, GC) << "Waited for task end for " << Timing::PrettyTimeNs(end_waiting - start_waiting); + LOG(INFO, GC) << time::GetCurrentTimeString() << "Waited for task end for " + << Timing::PrettyTimeNs(end_waiting - start_waiting); + os::CpuAffinityManager::PringCurrentAffinity(); } } // namespace panda::mem diff --git a/runtime/mem/gc/gc_workers_thread_pool.h b/runtime/mem/gc/gc_workers_thread_pool.h index aac9d3061..8be963652 100644 --- a/runtime/mem/gc/gc_workers_thread_pool.h +++ b/runtime/mem/gc/gc_workers_thread_pool.h @@ -288,6 +288,7 @@ public: solved_tasks_++; if (solved_tasks_ == sended_tasks_) { os::memory::LockHolder lock(cond_var_lock_); + LOG(INFO, GC) << time::GetCurrentTimeString() << "IncreaseSolvedTasks, notify waiters"; cond_var_.Signal(); } } -- Gitee