Mon, 27 Apr 2009 16:52:18 -0700
6819098: G1: reduce RSet scanning times
Summary: Added a feedback-driven exponential skipping for parallel RSet scanning.
Reviewed-by: tonyp, apetrusenko
src/share/vm/gc_implementation/g1/g1RemSet.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp Mon Apr 27 12:33:57 2009 -0700 1.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp Mon Apr 27 16:52:18 2009 -0700 1.3 @@ -180,6 +180,7 @@ 1.4 CardTableModRefBS *_ct_bs; 1.5 int _worker_i; 1.6 bool _try_claimed; 1.7 + size_t _min_skip_distance, _max_skip_distance; 1.8 public: 1.9 ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) : 1.10 _oc(oc), 1.11 @@ -191,6 +192,8 @@ 1.12 _g1h = G1CollectedHeap::heap(); 1.13 _bot_shared = _g1h->bot_shared(); 1.14 _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set()); 1.15 + _min_skip_distance = 16; 1.16 + _max_skip_distance = 2 * _g1h->n_par_threads() * _min_skip_distance; 1.17 } 1.18 1.19 void set_try_claimed() { _try_claimed = true; } 1.20 @@ -245,9 +248,13 @@ 1.21 HeapRegionRemSetIterator* iter = _g1h->rem_set_iterator(_worker_i); 1.22 hrrs->init_iterator(iter); 1.23 size_t card_index; 1.24 + size_t skip_distance = 0, current_card = 0, jump_to_card = 0; 1.25 while (iter->has_next(card_index)) { 1.26 + if (current_card < jump_to_card) { 1.27 + ++current_card; 1.28 + continue; 1.29 + } 1.30 HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index); 1.31 - 1.32 #if 0 1.33 gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n", 1.34 card_start, card_start + CardTableModRefBS::card_size_in_words); 1.35 @@ -257,20 +264,28 @@ 1.36 assert(card_region != NULL, "Yielding cards not in the heap?"); 1.37 _cards++; 1.38 1.39 - if (!card_region->in_collection_set()) { 1.40 - // If the card is dirty, then we will scan it during updateRS. 1.41 - if (!_ct_bs->is_card_claimed(card_index) && 1.42 - !_ct_bs->is_card_dirty(card_index)) { 1.43 - assert(_ct_bs->is_card_clean(card_index) || 1.44 - _ct_bs->is_card_claimed(card_index) || 1.45 - _ct_bs->is_card_deferred(card_index), 1.46 - "Card is either clean, claimed or deferred"); 1.47 - if (_ct_bs->claim_card(card_index)) 1.48 + // If the card is dirty, then we will scan it during updateRS. 1.49 + if (!card_region->in_collection_set() && !_ct_bs->is_card_dirty(card_index)) { 1.50 + if (!_ct_bs->is_card_claimed(card_index) && _ct_bs->claim_card(card_index)) { 1.51 scanCard(card_index, card_region); 1.52 - } 1.53 + } else if (_try_claimed) { 1.54 + if (jump_to_card == 0 || jump_to_card != current_card) { 1.55 + // We did some useful work in the previous iteration. 1.56 + // Decrease the distance. 1.57 + skip_distance = MAX2(skip_distance >> 1, _min_skip_distance); 1.58 + } else { 1.59 + // Previous iteration resulted in a claim failure. 1.60 + // Increase the distance. 1.61 + skip_distance = MIN2(skip_distance << 1, _max_skip_distance); 1.62 + } 1.63 + jump_to_card = current_card + skip_distance; 1.64 + } 1.65 } 1.66 + ++current_card; 1.67 } 1.68 - hrrs->set_iter_complete(); 1.69 + if (!_try_claimed) { 1.70 + hrrs->set_iter_complete(); 1.71 + } 1.72 return false; 1.73 } 1.74 // Set all cards back to clean.