migration/xbzrle: add encoding rate
Users may need to check the xbzrle encoding rate to know if the guest memory is xbzrle encoding-friendly, and dynamically turn off the encoding if the encoding rate is low. Signed-off-by: Yi Sun <yi.y.sun@intel.com> Signed-off-by: Wei Wang <wei.w.wang@intel.com> Message-Id: <1588208375-19556-1-git-send-email-wei.w.wang@intel.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
This commit is contained in:
parent
59c59c67ee
commit
e460a4b1a4
@ -932,6 +932,7 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s)
|
||||
info->xbzrle_cache->pages = xbzrle_counters.pages;
|
||||
info->xbzrle_cache->cache_miss = xbzrle_counters.cache_miss;
|
||||
info->xbzrle_cache->cache_miss_rate = xbzrle_counters.cache_miss_rate;
|
||||
info->xbzrle_cache->encoding_rate = xbzrle_counters.encoding_rate;
|
||||
info->xbzrle_cache->overflow = xbzrle_counters.overflow;
|
||||
}
|
||||
|
||||
|
@ -327,6 +327,10 @@ struct RAMState {
|
||||
uint64_t num_dirty_pages_period;
|
||||
/* xbzrle misses since the beginning of the period */
|
||||
uint64_t xbzrle_cache_miss_prev;
|
||||
/* Amount of xbzrle pages since the beginning of the period */
|
||||
uint64_t xbzrle_pages_prev;
|
||||
/* Amount of xbzrle encoded bytes since the beginning of the period */
|
||||
uint64_t xbzrle_bytes_prev;
|
||||
|
||||
/* compression statistics since the beginning of the period */
|
||||
/* amount of count that no free thread to compress data */
|
||||
@ -710,6 +714,18 @@ static int save_xbzrle_page(RAMState *rs, uint8_t **current_data,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reaching here means the page has hit the xbzrle cache, no matter what
|
||||
* encoding result it is (normal encoding, overflow or skipping the page),
|
||||
* count the page as encoded. This is used to caculate the encoding rate.
|
||||
*
|
||||
* Example: 2 pages (8KB) being encoded, first page encoding generates 2KB,
|
||||
* 2nd page turns out to be skipped (i.e. no new bytes written to the
|
||||
* page), the overall encoding rate will be 8KB / 2KB = 4, which has the
|
||||
* skipped page included. In this way, the encoding rate can tell if the
|
||||
* guest page is good for xbzrle encoding.
|
||||
*/
|
||||
xbzrle_counters.pages++;
|
||||
prev_cached_page = get_cached_data(XBZRLE.cache, current_addr);
|
||||
|
||||
/* save current buffer into memory */
|
||||
@ -740,6 +756,7 @@ static int save_xbzrle_page(RAMState *rs, uint8_t **current_data,
|
||||
} else if (encoded_len == -1) {
|
||||
trace_save_xbzrle_page_overflow();
|
||||
xbzrle_counters.overflow++;
|
||||
xbzrle_counters.bytes += TARGET_PAGE_SIZE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -750,8 +767,12 @@ static int save_xbzrle_page(RAMState *rs, uint8_t **current_data,
|
||||
qemu_put_be16(rs->f, encoded_len);
|
||||
qemu_put_buffer(rs->f, XBZRLE.encoded_buf, encoded_len);
|
||||
bytes_xbzrle += encoded_len + 1 + 2;
|
||||
xbzrle_counters.pages++;
|
||||
xbzrle_counters.bytes += bytes_xbzrle;
|
||||
/*
|
||||
* Like compressed_size (please see update_compress_thread_counts),
|
||||
* the xbzrle encoded bytes don't count the 8 byte header with
|
||||
* RAM_SAVE_FLAG_CONTINUE.
|
||||
*/
|
||||
xbzrle_counters.bytes += bytes_xbzrle - 8;
|
||||
ram_counters.transferred += bytes_xbzrle;
|
||||
|
||||
return 1;
|
||||
@ -884,9 +905,23 @@ static void migration_update_rates(RAMState *rs, int64_t end_time)
|
||||
}
|
||||
|
||||
if (migrate_use_xbzrle()) {
|
||||
double encoded_size, unencoded_size;
|
||||
|
||||
xbzrle_counters.cache_miss_rate = (double)(xbzrle_counters.cache_miss -
|
||||
rs->xbzrle_cache_miss_prev) / page_count;
|
||||
rs->xbzrle_cache_miss_prev = xbzrle_counters.cache_miss;
|
||||
unencoded_size = (xbzrle_counters.pages - rs->xbzrle_pages_prev) *
|
||||
TARGET_PAGE_SIZE;
|
||||
encoded_size = xbzrle_counters.bytes - rs->xbzrle_bytes_prev;
|
||||
if (xbzrle_counters.pages == rs->xbzrle_pages_prev) {
|
||||
xbzrle_counters.encoding_rate = 0;
|
||||
} else if (!encoded_size) {
|
||||
xbzrle_counters.encoding_rate = UINT64_MAX;
|
||||
} else {
|
||||
xbzrle_counters.encoding_rate = unencoded_size / encoded_size;
|
||||
}
|
||||
rs->xbzrle_pages_prev = xbzrle_counters.pages;
|
||||
rs->xbzrle_bytes_prev = xbzrle_counters.bytes;
|
||||
}
|
||||
|
||||
if (migrate_use_compression()) {
|
||||
|
@ -303,6 +303,8 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
|
||||
info->xbzrle_cache->cache_miss);
|
||||
monitor_printf(mon, "xbzrle cache miss rate: %0.2f\n",
|
||||
info->xbzrle_cache->cache_miss_rate);
|
||||
monitor_printf(mon, "xbzrle encoding rate: %0.2f\n",
|
||||
info->xbzrle_cache->encoding_rate);
|
||||
monitor_printf(mon, "xbzrle overflow: %" PRIu64 "\n",
|
||||
info->xbzrle_cache->overflow);
|
||||
}
|
||||
|
@ -70,6 +70,8 @@
|
||||
#
|
||||
# @cache-miss-rate: rate of cache miss (since 2.1)
|
||||
#
|
||||
# @encoding-rate: rate of encoded bytes (since 5.1)
|
||||
#
|
||||
# @overflow: number of overflows
|
||||
#
|
||||
# Since: 1.2
|
||||
@ -77,7 +79,7 @@
|
||||
{ 'struct': 'XBZRLECacheStats',
|
||||
'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int',
|
||||
'cache-miss': 'int', 'cache-miss-rate': 'number',
|
||||
'overflow': 'int' } }
|
||||
'encoding-rate': 'number', 'overflow': 'int' } }
|
||||
|
||||
##
|
||||
# @CompressionStats:
|
||||
@ -337,6 +339,7 @@
|
||||
# "pages":2444343,
|
||||
# "cache-miss":2244,
|
||||
# "cache-miss-rate":0.123,
|
||||
# "encoding-rate":80.1,
|
||||
# "overflow":34434
|
||||
# }
|
||||
# }
|
||||
|
Loading…
Reference in New Issue
Block a user