123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247(*
* Copyright (c) 2018-2022 Tarides <contact@tarides.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)moduleSummary=Trace_stat_summarymoduleUtils=Trace_stat_summary_utilstypemetrics=(string*floatlist)list[@@derivingrepr]letmetrics_t=Irmin.Type.(Json.assoc(listfloat))typeresult={name:string;metrics:metrics}[@@derivingrepr]typet={results:(result[@nobuiltin])list}[@@derivingrepr](** As of may 2021, outputing "nan" strings in place of numbers crashes the CB.
Let's just filter those out since this is functionally identical. *)letfilter_nans_outresults=List.map(fun{name;metrics}->letmetrics=List.map(fun(name,l)->(name,matchlwith[v]whenFloat.is_nanv->[]|l->l))metricsin{name;metrics})resultsletcreate_raw_results0s:resultlist=letopenSummaryin[{name="Trace Replay - main metrics";metrics=[("CPU time elapsed (s)",[s.elapsed_cpu]);("TZ-transactions per sec",[(Utils.approx_transaction_count_of_block_counts.block_count|>float_of_int)/.s.elapsed_cpu;]);("TZ-operations per sec",[(Utils.approx_operation_count_of_block_counts.block_count|>float_of_int)/.s.elapsed_cpu;]);("Context.set per sec",[fst(Span.Map.find`Adds.span).cumu_count.max_value/.s.elapsed_cpu;]);("tail latency (s)",[fst(Span.Map.find`Commits.span).duration.max_value]);];};{name="Trace Replay - resource usage - disk IO (total)";metrics=[("IOPS (op/s)",[s.index.nb_both.value_after_commit.diff/.s.elapsed_cpu]);("throughput (MB/s)",[s.index.bytes_both.value_after_commit.diff/.s.elapsed_cpu/.1e6;]);("total (MB)",[s.index.bytes_both.value_after_commit.diff/.1e6]);];};{name="Trace Replay - resource usage - disk IO (read)";metrics=[("IOPS (op/s)",[s.index.nb_reads.value_after_commit.diff/.s.elapsed_cpu]);("throughput (MB/s)",[s.index.bytes_read.value_after_commit.diff/.s.elapsed_cpu/.1e6;]);("total (MB)",[s.index.bytes_read.value_after_commit.diff/.1e6]);];};{name="Trace Replay - resource usage - disk IO (write)";metrics=[("IOPS (op/s)",[s.index.nb_writes.value_after_commit.diff/.s.elapsed_cpu]);("throughput (MB/s)",[s.index.bytes_written.value_after_commit.diff/.s.elapsed_cpu/.1e6;]);("total (MB)",[s.index.bytes_written.value_after_commit.diff/.1e6]);];};{name="Trace Replay - resource usage - misc.";metrics=[("max memory usage (GB)",[List.fold_leftmax0.s.gc.major_heap_top_bytes/.1e9]);("mean CPU usage",[s.elapsed_cpu/.s.elapsed_wall]);];};]letcreate_raw_results1s:resultlist=leta=letname="Trace Replay - Context Phases Length"inletopenTrace_stat_summaryinletmetrics=[`Block;`Buildup;`Commit]|>List.map@@funk->letvs=Span.(Map.findks.span).durationin(Printf.sprintf"%s (ms)"(Span.Key.to_stringk),[vs.mean*.1000.(* TODO: {min / max / avg}, maybe on a log scale? *);])in{name;metrics}inletb=letname="Trace Replay - Context Buildup Lengths"inletopenTrace_stat_summaryinletmetrics=[`Add;`Remove;`Find;`Mem;`Mem_tree;`Copy;`Unseen]|>List.map@@funk->letvs=Span.(Map.findks.span).durationin(Printf.sprintf"%s (\xc2\xb5s)"(Span.Key.to_stringk),[vs.mean*.1e6(* TODO: {min / max / avg}, maybe on a log scale? *);])in{name;metrics}in[a;b]letcreate_raw_results2s:resultlist=letname="Trace Replay - irmin-pack Global Stats"inletmetrics=letopenSummaryin[("finds",s.pack.finds.total);("finds.from_staging",s.pack.finds.from_staging);("finds.from_lru",s.pack.finds.from_lru);("finds.from_pack_direct",s.pack.finds.from_pack_direct);("finds.from_pack_indexed",s.pack.finds.from_pack_indexed);("finds.missing",s.pack.finds.missing);("finds.cache_miss",s.pack.finds.cache_miss);("appended_hashes",s.pack.appended_hashes);("appended_offsets",s.pack.appended_offsets);("inode_add",s.pack.inode_add);("inode_remove",s.pack.inode_remove);("inode_of_seq",s.pack.inode_of_seq);("inode_of_raw",s.pack.inode_of_raw);("inode_rec_add",s.pack.inode_rec_add);("inode_rec_remove",s.pack.inode_rec_remove);("inode_to_binv",s.pack.inode_to_binv);("inode_decode_bin",s.pack.inode_decode_bin);("inode_encode_bin",s.pack.inode_encode_bin);]|>List.map@@fun(name,lbs)->(name,[lbs.value_after_commit.diff])in[{name;metrics}]letcreate_raw_results3s:resultlist=letname="Trace Replay - irmin.tree Global Stats"inletopenTrace_stat_summaryinletmetrics=[("contents_hash",s.tree.contents_hash);("contents_find",s.tree.contents_find);("contents_add",s.tree.contents_add);("node_hash",s.tree.node_hash);("node_mem",s.tree.node_mem);("node_add",s.tree.node_add);("node_find",s.tree.node_find);("node_val_v",s.tree.node_val_v);("node_val_find",s.tree.node_val_find);("node_val_list",s.tree.node_val_list);]|>List.map@@fun(name,lbs)->(name,[lbs.value_after_commit.diff])in[{name;metrics}]letcreate_raw_results4s:resultlist=letname="Trace Replay - index Stats"inletopenTrace_stat_summaryinletmetrics=[("cumu data MB",[fsts.index.cumu_data_bytes.value_after_commit.max_value*.1e-6]);("merge count",[s.index.nb_merge.value_after_commit.diff]);]in[{name;metrics}]letcreate_raw_results5s:resultlist=letname="Trace Replay - GC Stats"inletopenTrace_stat_summaryinletmetrics=[("minor words allocated",s.gc.minor_words);("major words allocated",s.gc.major_words);("minor collections",s.gc.minor_collections);("major collections",s.gc.major_collections);("promoted words",s.gc.promoted_words);("compactions",s.gc.compactions);]|>List.map@@fun(name,lbs)->(name,[lbs.value_after_commit.diff])inletmetrics'=[("avg major heap MB after commit",[s.gc.major_heap_bytes.value_after_commit.mean/.1e6]);]in[{name;metrics=metrics@metrics'}]letof_summarys={results=create_raw_results0s@create_raw_results1s@create_raw_results2s@create_raw_results3s@create_raw_results4s@create_raw_results5s|>filter_nans_out;}