in tools/block_cache_analyzer/block_cache_trace_analyzer.cc [2110:2305]
int block_cache_trace_analyzer_tool(int argc, char** argv) {
ParseCommandLineFlags(&argc, &argv, true);
if (FLAGS_block_cache_trace_path.empty()) {
fprintf(stderr, "block cache trace path is empty\n");
exit(1);
}
uint64_t warmup_seconds =
FLAGS_cache_sim_warmup_seconds > 0 ? FLAGS_cache_sim_warmup_seconds : 0;
uint32_t downsample_ratio = FLAGS_block_cache_trace_downsample_ratio > 0
? FLAGS_block_cache_trace_downsample_ratio
: 0;
std::vector<CacheConfiguration> cache_configs =
parse_cache_config_file(FLAGS_block_cache_sim_config_path);
std::unique_ptr<BlockCacheTraceSimulator> cache_simulator;
if (!cache_configs.empty()) {
cache_simulator.reset(new BlockCacheTraceSimulator(
warmup_seconds, downsample_ratio, cache_configs));
Status s = cache_simulator->InitializeCaches();
if (!s.ok()) {
fprintf(stderr, "Cannot initialize cache simulators %s\n",
s.ToString().c_str());
exit(1);
}
}
BlockCacheTraceAnalyzer analyzer(
FLAGS_block_cache_trace_path, FLAGS_block_cache_analysis_result_dir,
FLAGS_human_readable_trace_file_path,
!FLAGS_reuse_distance_labels.empty(), FLAGS_mrc_only,
FLAGS_is_block_cache_human_readable_trace, std::move(cache_simulator));
Status s = analyzer.Analyze();
if (!s.IsIncomplete() && !s.ok()) {
// Read all traces.
fprintf(stderr, "Cannot process the trace %s\n", s.ToString().c_str());
exit(1);
}
fprintf(stdout, "Status: %s\n", s.ToString().c_str());
analyzer.WriteMissRatioCurves();
analyzer.WriteMissRatioTimeline(1);
analyzer.WriteMissRatioTimeline(kSecondInMinute);
analyzer.WriteMissRatioTimeline(kSecondInHour);
analyzer.WriteMissTimeline(1);
analyzer.WriteMissTimeline(kSecondInMinute);
analyzer.WriteMissTimeline(kSecondInHour);
if (FLAGS_mrc_only) {
fprintf(stdout,
"Skipping the analysis statistics since the user wants to compute "
"MRC only");
return 0;
}
analyzer.PrintStatsSummary();
if (FLAGS_print_access_count_stats) {
print_break_lines(/*num_break_lines=*/3);
analyzer.PrintAccessCountStats(
/*user_access_only=*/false, FLAGS_analyze_bottom_k_access_count_blocks,
FLAGS_analyze_top_k_access_count_blocks);
print_break_lines(/*num_break_lines=*/3);
analyzer.PrintAccessCountStats(
/*user_access_only=*/true, FLAGS_analyze_bottom_k_access_count_blocks,
FLAGS_analyze_top_k_access_count_blocks);
}
if (FLAGS_print_block_size_stats) {
print_break_lines(/*num_break_lines=*/3);
analyzer.PrintBlockSizeStats();
}
if (FLAGS_print_data_block_access_count_stats) {
print_break_lines(/*num_break_lines=*/3);
analyzer.PrintDataBlockAccessStats();
}
print_break_lines(/*num_break_lines=*/3);
if (!FLAGS_timeline_labels.empty()) {
std::stringstream ss(FLAGS_timeline_labels);
while (ss.good()) {
std::string label;
getline(ss, label, ',');
if (label.find("block") != std::string::npos) {
analyzer.WriteAccessTimeline(label, kSecondInMinute, true);
analyzer.WriteAccessTimeline(label, kSecondInMinute, false);
analyzer.WriteAccessTimeline(label, kSecondInHour, true);
analyzer.WriteAccessTimeline(label, kSecondInHour, false);
} else {
analyzer.WriteAccessTimeline(label, kSecondInMinute, false);
analyzer.WriteAccessTimeline(label, kSecondInHour, false);
}
}
}
if (!FLAGS_analyze_callers.empty()) {
analyzer.WritePercentAccessSummaryStats();
std::stringstream ss(FLAGS_analyze_callers);
while (ss.good()) {
std::string caller;
getline(ss, caller, ',');
analyzer.WriteDetailedPercentAccessSummaryStats(string_to_caller(caller));
}
}
if (!FLAGS_access_count_buckets.empty()) {
std::vector<uint64_t> buckets = parse_buckets(FLAGS_access_count_buckets);
analyzer.WriteAccessCountSummaryStats(buckets, /*user_access_only=*/true);
analyzer.WriteAccessCountSummaryStats(buckets, /*user_access_only=*/false);
}
if (!FLAGS_reuse_distance_labels.empty() &&
!FLAGS_reuse_distance_buckets.empty()) {
std::vector<uint64_t> buckets = parse_buckets(FLAGS_reuse_distance_buckets);
std::stringstream ss(FLAGS_reuse_distance_labels);
while (ss.good()) {
std::string label;
getline(ss, label, ',');
analyzer.WriteReuseDistance(label, buckets);
}
}
if (!FLAGS_reuse_interval_labels.empty() &&
!FLAGS_reuse_interval_buckets.empty()) {
std::vector<uint64_t> buckets = parse_buckets(FLAGS_reuse_interval_buckets);
std::stringstream ss(FLAGS_reuse_interval_labels);
while (ss.good()) {
std::string label;
getline(ss, label, ',');
analyzer.WriteReuseInterval(label, buckets);
}
}
if (!FLAGS_reuse_lifetime_labels.empty() &&
!FLAGS_reuse_lifetime_buckets.empty()) {
std::vector<uint64_t> buckets = parse_buckets(FLAGS_reuse_lifetime_buckets);
std::stringstream ss(FLAGS_reuse_lifetime_labels);
while (ss.good()) {
std::string label;
getline(ss, label, ',');
analyzer.WriteReuseLifetime(label, buckets);
}
}
if (FLAGS_analyze_blocks_reuse_k_reuse_window != 0) {
std::vector<TraceType> block_types{TraceType::kBlockTraceIndexBlock,
TraceType::kBlockTraceDataBlock,
TraceType::kBlockTraceFilterBlock};
for (auto block_type : block_types) {
analyzer.WriteBlockReuseTimeline(
FLAGS_analyze_blocks_reuse_k_reuse_window,
/*user_access_only=*/true, block_type);
analyzer.WriteBlockReuseTimeline(
FLAGS_analyze_blocks_reuse_k_reuse_window,
/*user_access_only=*/false, block_type);
}
}
if (!FLAGS_analyze_get_spatial_locality_labels.empty() &&
!FLAGS_analyze_get_spatial_locality_buckets.empty()) {
std::vector<uint64_t> buckets =
parse_buckets(FLAGS_analyze_get_spatial_locality_buckets);
std::stringstream ss(FLAGS_analyze_get_spatial_locality_labels);
while (ss.good()) {
std::string label;
getline(ss, label, ',');
analyzer.WriteGetSpatialLocality(label, buckets);
}
}
if (!FLAGS_analyze_correlation_coefficients_labels.empty()) {
std::stringstream ss(FLAGS_analyze_correlation_coefficients_labels);
while (ss.good()) {
std::string label;
getline(ss, label, ',');
analyzer.WriteCorrelationFeatures(
label, FLAGS_analyze_correlation_coefficients_max_number_of_values);
}
analyzer.WriteCorrelationFeaturesForGet(
FLAGS_analyze_correlation_coefficients_max_number_of_values);
}
if (!FLAGS_skew_labels.empty() && !FLAGS_skew_buckets.empty()) {
std::vector<uint64_t> buckets = parse_buckets(FLAGS_skew_buckets);
std::stringstream ss(FLAGS_skew_labels);
while (ss.good()) {
std::string label;
getline(ss, label, ',');
if (label.find("block") != std::string::npos) {
analyzer.WriteSkewness(label, buckets,
TraceType::kBlockTraceIndexBlock);
analyzer.WriteSkewness(label, buckets,
TraceType::kBlockTraceFilterBlock);
analyzer.WriteSkewness(label, buckets, TraceType::kBlockTraceDataBlock);
analyzer.WriteSkewness(label, buckets, TraceType::kTraceMax);
} else {
analyzer.WriteSkewness(label, buckets, TraceType::kTraceMax);
}
}
}
return 0;
}