 Chromium Code Reviews
 Chromium Code Reviews Issue 1410633005:
  [heap] Base number of compaction tasks on live memory and compaction speed.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 1410633005:
  [heap] Base number of compaction tasks on live memory and compaction speed.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| Index: src/heap/mark-compact.cc | 
| diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc | 
| index e73dfc335481af7063d5b482a5d1c341d1521f7b..54b7898ac87d94010c00b2810880ff2542d9bd3c 100644 | 
| --- a/src/heap/mark-compact.cc | 
| +++ b/src/heap/mark-compact.cc | 
| @@ -3310,22 +3310,26 @@ bool MarkCompactCollector::EvacuateLiveObjectsFromPage( | 
| int MarkCompactCollector::NumberOfParallelCompactionTasks() { | 
| if (!FLAG_parallel_compaction) return 1; | 
| // We cap the number of parallel compaction tasks by | 
| - // - (#cores - 1) | 
| - // - a value depending on the live memory in evacuation candidates | 
| // - a hard limit | 
| - // | 
| - // TODO(mlippautz): Instead of basing the limit on live memory, we could also | 
| - // compute the number from the time it takes to evacuate memory and a given | 
| - // desired time in which compaction should be finished. | 
| - const int kLiveMemoryPerCompactionTask = 2 * Page::kPageSize; | 
| + // - (#cores - 1) | 
| + // - a target compaction time, considering compaction speed and live memory | 
| + const double kTargetCompactionTimeInMs = 2; | 
| 
Hannes Payer (out of office)
2015/11/03 04:08:17
Let's aim for 1 ms. Keep the constant, it has at l
 
Michael Lippautz
2015/11/03 20:57:42
Done.
I also restructured the bottom part (return
 | 
| const int kMaxCompactionTasks = 8; | 
| - int live_bytes = 0; | 
| + | 
| + intptr_t compaction_speed = | 
| + heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); | 
| + if (compaction_speed == 0) return 1; | 
| + | 
| + intptr_t live_bytes = 0; | 
| for (Page* page : evacuation_candidates_) { | 
| live_bytes += page->LiveBytes(); | 
| } | 
| - return Min(kMaxCompactionTasks, | 
| - Min(1 + live_bytes / kLiveMemoryPerCompactionTask, | 
| - Max(1, base::SysInfo::NumberOfProcessors() - 1))); | 
| + | 
| + return Min( | 
| + kMaxCompactionTasks, | 
| + Min(1 + static_cast<int>(static_cast<double>(live_bytes) / | 
| + compaction_speed / kTargetCompactionTimeInMs), | 
| + Max(1, base::SysInfo::NumberOfProcessors() - 1))); | 
| } | 
| @@ -3333,8 +3337,18 @@ void MarkCompactCollector::EvacuatePagesInParallel() { | 
| const int num_pages = evacuation_candidates_.length(); | 
| if (num_pages == 0) return; | 
| + // Used for trace summary. | 
| + intptr_t live_bytes = 0; | 
| + intptr_t compaction_speed = 0; | 
| + if (FLAG_trace_fragmentation) { | 
| + for (Page* page : evacuation_candidates_) { | 
| + live_bytes += page->LiveBytes(); | 
| + } | 
| + compaction_speed = heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); | 
| + } | 
| const int num_tasks = NumberOfParallelCompactionTasks(); | 
| + | 
| // Set up compaction spaces. | 
| CompactionSpaceCollection** compaction_spaces_for_tasks = | 
| new CompactionSpaceCollection*[num_tasks]; | 
| @@ -3361,15 +3375,20 @@ void MarkCompactCollector::EvacuatePagesInParallel() { | 
| WaitUntilCompactionCompleted(); | 
| + double compaction_duration = 0.0; | 
| + intptr_t compacted_memory = 0; | 
| // Merge back memory (compacted and unused) from compaction spaces. | 
| for (int i = 0; i < num_tasks; i++) { | 
| heap()->old_space()->MergeCompactionSpace( | 
| compaction_spaces_for_tasks[i]->Get(OLD_SPACE)); | 
| heap()->code_space()->MergeCompactionSpace( | 
| compaction_spaces_for_tasks[i]->Get(CODE_SPACE)); | 
| + compacted_memory += compaction_spaces_for_tasks[i]->bytes_compacted(); | 
| + compaction_duration += compaction_spaces_for_tasks[i]->duration(); | 
| delete compaction_spaces_for_tasks[i]; | 
| } | 
| delete[] compaction_spaces_for_tasks; | 
| + heap()->tracer()->AddCompactionEvent(compaction_duration, compacted_memory); | 
| // Finalize sequentially. | 
| int abandoned_pages = 0; | 
| @@ -3410,10 +3429,12 @@ void MarkCompactCollector::EvacuatePagesInParallel() { | 
| if (FLAG_trace_fragmentation) { | 
| PrintIsolate(isolate(), | 
| "%8.0f ms: compaction: parallel=%d pages=%d aborted=%d " | 
| - "tasks=%d cores=%d\n", | 
| + "tasks=%d cores=%d live_bytes=%" V8_PTR_PREFIX | 
| + "d compaction_speed=%" V8_PTR_PREFIX "d\n", | 
| isolate()->time_millis_since_init(), FLAG_parallel_compaction, | 
| num_pages, abandoned_pages, num_tasks, | 
| - base::SysInfo::NumberOfProcessors()); | 
| + base::SysInfo::NumberOfProcessors(), live_bytes, | 
| + compaction_speed); | 
| } | 
| } | 
| @@ -3441,11 +3462,15 @@ void MarkCompactCollector::EvacuatePages( | 
| if (p->IsEvacuationCandidate()) { | 
| DCHECK_EQ(p->parallel_compaction_state().Value(), | 
| MemoryChunk::kCompactingInProgress); | 
| + double start = heap_->MonotonicallyIncreasingTimeInMs(); | 
| + intptr_t live_bytes = p->LiveBytes(); | 
| 
Hannes Payer (out of office)
2015/11/03 04:08:17
Let's move the time measuring into EvacuateLiveObj
 
Michael Lippautz
2015/11/03 20:57:42
Done.
 | 
| if (EvacuateLiveObjectsFromPage( | 
| p, compaction_spaces->Get(p->owner()->identity()), | 
| evacuation_slots_buffer)) { | 
| p->parallel_compaction_state().SetValue( | 
| MemoryChunk::kCompactingFinalize); | 
| + compaction_spaces->ReportCompactionProgress( | 
| + heap_->MonotonicallyIncreasingTimeInMs() - start, live_bytes); | 
| } else { | 
| p->parallel_compaction_state().SetValue( | 
| MemoryChunk::kCompactingAborted); |