diff options
author | Stephen Dolan <sdolan@janestreet.com> | 2019-05-27 13:22:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-27 13:22:39 +0100 |
commit | 455bd0ffae85a9b63cb331ac532ea2ab52fe418c (patch) | |
tree | 9d54f0a42416a5f7d5646eb710cc090de17a6040 | |
parent | 393dc1d3ce500174ba8d94db0dd34bd48ea549fe (diff) | |
parent | 16611aacc150adec0b801cf1a5b1e5989261c8d3 (diff) | |
download | ocaml-455bd0ffae85a9b63cb331ac532ea2ab52fe418c.tar.gz |
Merge pull request #8684 from jhjourdan/memprof_binomial
Use binomial distribution instead of Poisson distribution in Memprof
-rw-r--r-- | runtime/.depend | 64 | ||||
-rw-r--r-- | runtime/caml/memory.h | 2 | ||||
-rw-r--r-- | runtime/caml/misc.h | 3 | ||||
-rw-r--r-- | runtime/intern.c | 2 | ||||
-rw-r--r-- | runtime/memory.c | 4 | ||||
-rw-r--r-- | runtime/memprof.c | 209 | ||||
-rw-r--r-- | runtime/signals_nat.c | 8 | ||||
-rw-r--r-- | stdlib/gc.mli | 32 | ||||
-rw-r--r-- | testsuite/tests/statmemprof/arrays_in_major.byte.reference | 8 | ||||
-rw-r--r-- | testsuite/tests/statmemprof/arrays_in_major.ml | 31 | ||||
-rw-r--r-- | testsuite/tests/statmemprof/arrays_in_major.opt.reference | 8 | ||||
-rw-r--r-- | testsuite/tests/statmemprof/arrays_in_minor.byte.reference | 6 | ||||
-rw-r--r-- | testsuite/tests/statmemprof/arrays_in_minor.ml | 29 | ||||
-rw-r--r-- | testsuite/tests/statmemprof/arrays_in_minor.opt.reference | 6 | ||||
-rw-r--r-- | testsuite/tests/statmemprof/exception_callback.ml | 6 | ||||
-rw-r--r-- | testsuite/tests/statmemprof/exception_callback.reference | 2 | ||||
-rw-r--r-- | testsuite/tests/statmemprof/lists_in_minor.byte.reference | 6 | ||||
-rw-r--r-- | testsuite/tests/statmemprof/lists_in_minor.ml | 17 |
18 files changed, 211 insertions, 232 deletions
diff --git a/runtime/.depend b/runtime/.depend index df5b6c69bc..b110cd17ed 100644 --- a/runtime/.depend +++ b/runtime/.depend @@ -177,7 +177,7 @@ memprof_b.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \ caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \ - caml/stack.h + caml/stack.h caml/misc.h meta_b.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \ caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ @@ -210,7 +210,7 @@ printexc_b.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \ caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/memprof.h + caml/address_class.h caml/memprof.h caml/memprof.h roots_byt_b.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -225,13 +225,13 @@ signals_byt_b.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/signals_machdep.h caml/memprof.h + caml/signals_machdep.h signals_b.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \ caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - caml/sys.h + caml/sys.h caml/memprof.h signals_nat_b.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -490,7 +490,7 @@ memprof_bd.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \ caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \ - caml/stack.h + caml/stack.h caml/misc.h meta_bd.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \ caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ @@ -523,7 +523,7 @@ printexc_bd.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \ caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/memprof.h + caml/address_class.h caml/memprof.h caml/memprof.h roots_byt_bd.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -538,13 +538,13 @@ signals_byt_bd.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/signals_machdep.h caml/memprof.h + caml/signals_machdep.h signals_bd.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \ caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - caml/sys.h + caml/sys.h caml/memprof.h signals_nat_bd.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -799,7 +799,7 @@ memprof_bi.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \ caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \ - caml/stack.h + caml/stack.h caml/misc.h meta_bi.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \ caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ @@ -832,7 +832,7 @@ printexc_bi.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \ caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/memprof.h + caml/address_class.h caml/memprof.h caml/memprof.h roots_byt_bi.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -847,13 +847,13 @@ signals_byt_bi.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/signals_machdep.h caml/memprof.h + caml/signals_machdep.h signals_bi.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \ caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - caml/sys.h + caml/sys.h caml/memprof.h signals_nat_bi.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -1108,7 +1108,7 @@ memprof_bpic.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \ caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \ - caml/stack.h + caml/stack.h caml/misc.h meta_bpic.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \ caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ @@ -1141,7 +1141,7 @@ printexc_bpic.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \ caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/memprof.h + caml/address_class.h caml/memprof.h caml/memprof.h roots_byt_bpic.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -1156,13 +1156,13 @@ signals_byt_bpic.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/signals_machdep.h caml/memprof.h + caml/signals_machdep.h signals_bpic.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \ caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - caml/sys.h + caml/sys.h caml/memprof.h signals_nat_bpic.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -1414,7 +1414,7 @@ memprof_n.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \ caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \ - caml/stack.h + caml/stack.h caml/misc.h meta_n.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \ caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ @@ -1447,7 +1447,7 @@ printexc_n.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \ caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/memprof.h + caml/address_class.h caml/memprof.h caml/memprof.h roots_byt_n.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -1462,13 +1462,13 @@ signals_byt_n.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/signals_machdep.h caml/memprof.h + caml/signals_machdep.h signals_n.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \ caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - caml/sys.h + caml/sys.h caml/memprof.h signals_nat_n.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -1724,7 +1724,7 @@ memprof_nd.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \ caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \ - caml/stack.h + caml/stack.h caml/misc.h meta_nd.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \ caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ @@ -1757,7 +1757,7 @@ printexc_nd.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \ caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/memprof.h + caml/address_class.h caml/memprof.h caml/memprof.h roots_byt_nd.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -1772,13 +1772,13 @@ signals_byt_nd.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/signals_machdep.h caml/memprof.h + caml/signals_machdep.h signals_nd.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \ caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - caml/sys.h + caml/sys.h caml/memprof.h signals_nat_nd.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -2030,7 +2030,7 @@ memprof_ni.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \ caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \ - caml/stack.h + caml/stack.h caml/misc.h meta_ni.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \ caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ @@ -2063,7 +2063,7 @@ printexc_ni.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \ caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/memprof.h + caml/address_class.h caml/memprof.h caml/memprof.h roots_byt_ni.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -2078,13 +2078,13 @@ signals_byt_ni.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/signals_machdep.h caml/memprof.h + caml/signals_machdep.h signals_ni.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \ caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - caml/sys.h + caml/sys.h caml/memprof.h signals_nat_ni.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -2336,7 +2336,7 @@ memprof_npic.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \ caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \ - caml/stack.h + caml/stack.h caml/misc.h meta_npic.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \ caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ @@ -2369,7 +2369,7 @@ printexc_npic.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \ caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/memprof.h + caml/address_class.h caml/memprof.h caml/memprof.h roots_byt_npic.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ @@ -2384,13 +2384,13 @@ signals_byt_npic.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/signals_machdep.h caml/memprof.h + caml/signals_machdep.h signals_npic.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \ caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \ caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - caml/sys.h + caml/sys.h caml/memprof.h signals_nat_npic.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \ caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ diff --git a/runtime/caml/memory.h b/runtime/caml/memory.h index 2ff2d194c0..038419abbc 100644 --- a/runtime/caml/memory.h +++ b/runtime/caml/memory.h @@ -45,7 +45,7 @@ CAMLextern value caml_alloc_shr_with_profinfo (mlsize_t, tag_t, intnat); #endif /* WITH_PROFINFO */ /* Variant of [caml_alloc_shr] where no memprof sampling is performed. */ -CAMLextern value caml_alloc_shr_no_track (mlsize_t, tag_t); +CAMLextern value caml_alloc_shr_no_track_noexc (mlsize_t, tag_t); /* Variant of [caml_alloc_shr] where no memprof sampling is performed, and re-using the profinfo associated with the header given in diff --git a/runtime/caml/misc.h b/runtime/caml/misc.h index 4466d292e7..1076a7a18d 100644 --- a/runtime/caml/misc.h +++ b/runtime/caml/misc.h @@ -179,6 +179,9 @@ static inline int caml_umul_overflow(uintnat a, uintnat b, uintnat * res) extern int caml_umul_overflow(uintnat a, uintnat b, uintnat * res); #endif +/* From floats.c */ +extern double caml_log1p(double); + /* Windows Unicode support */ #ifdef _WIN32 diff --git a/runtime/intern.c b/runtime/intern.c index 96cb74f8bf..f43999057e 100644 --- a/runtime/intern.c +++ b/runtime/intern.c @@ -633,7 +633,7 @@ static void intern_alloc(mlsize_t whsize, mlsize_t num_objects, #undef Restore_after_gc } }else{ - intern_block = caml_alloc_shr_no_track (wosize, String_tag); + intern_block = caml_alloc_shr_no_track_noexc (wosize, String_tag); /* do not do the urgent_gc check here because it might darken intern_block into gray and break the intern_color assertion below */ if (intern_block == 0) { diff --git a/runtime/memory.c b/runtime/memory.c index 4aee2dac3c..a4b76783e4 100644 --- a/runtime/memory.c +++ b/runtime/memory.c @@ -574,7 +574,7 @@ CAMLexport value caml_alloc_shr (mlsize_t wosize, tag_t tag) caml_spacetime_my_profinfo (NULL, wosize)); } -CAMLexport value caml_alloc_shr_no_track (mlsize_t wosize, tag_t tag) +CAMLexport value caml_alloc_shr_no_track_noexc (mlsize_t wosize, tag_t tag) { return caml_alloc_shr_aux (wosize, tag, 0, 0, caml_spacetime_my_profinfo (NULL, wosize)); @@ -585,7 +585,7 @@ CAMLexport value caml_alloc_shr (mlsize_t wosize, tag_t tag) return caml_alloc_shr_aux (wosize, tag, 1, 1, NO_PROFINFO); } -CAMLexport value caml_alloc_shr_no_track (mlsize_t wosize, tag_t tag) +CAMLexport value caml_alloc_shr_no_track_noexc (mlsize_t wosize, tag_t tag) { return caml_alloc_shr_aux (wosize, tag, 0, 0, NO_PROFINFO); } diff --git a/runtime/memprof.c b/runtime/memprof.c index c42663ed16..0f74b38241 100644 --- a/runtime/memprof.c +++ b/runtime/memprof.c @@ -27,6 +27,7 @@ #include "caml/backtrace_prim.h" #include "caml/weak.h" #include "caml/stack.h" +#include "caml/misc.h" static uint32_t mt_state[624]; static uint32_t mt_index; @@ -34,22 +35,21 @@ static uint32_t mt_index; /* [lambda] is the mean number of samples for each allocated word (including block headers). */ static double lambda = 0; - /* Inverse of [lamdba]. Meaningless if lamdba = 0 */ -static double lambda_inverse = 0; + /* Precomputed value of [1/log(1-lambda)], for fast sampling of + geometric distribution. + Dummy if [lambda = 0]. */ +static double one_log1m_lambda; int caml_memprof_suspended = 0; static intnat callstack_size = 0; static value memprof_callback = Val_unit; -/* Position of the next sample in the minor heap. Equals - [caml_young_alloc_start] if no sampling is planned in the current - minor heap. +/* Pointer to the word following the next sample in the minor + heap. Equals [caml_young_alloc_start] if no sampling is planned in + the current minor heap. Invariant: [caml_memprof_young_trigger <= caml_young_ptr]. */ value* caml_memprof_young_trigger; -/* The continuous position of the next minor sample within the next - sampled word. Always in [0, 1[. */ -static double next_sample_frac_part; /* Whether memprof has been initialized. */ static int init = 0; @@ -87,95 +87,42 @@ static double mt_generate_uniform(void) 1.16415321826934814453125e-10; /* 2^-33 */ } -/* C99's [lgammaf] function is not available in some compilers - (including MSVC). Here is our own approximate implementation of the - log-factorial function. - - Requirement: [n] is a non-negative integer. - - We use Ramanujan's formula. For n < 10^8, the absolute error is - less than 10^-6, which is way better than what we need. - */ -static double lfact(double n) +/* Simulate a geometric variable of parameter [lambda]. + The result is clipped in [1..Max_long] + Requires [lambda > 0]. */ +static uintnat mt_generate_geom() { - static double tab[10] = { - 0.0000000000, 0.0000000000, 0.6931471806, 1.7917594692, 3.1780538303, - 4.7874917428, 6.5792512120, 8.5251613611, 10.6046029027, 12.8018274801 }; - if(n < 10) - return tab[(int)n]; - return n*(log(n) - 1) + (1./6)*log(((8*n + 4)*n + 1)*n + 1./34) - + 0.5723649429; /* log(pi)/2 */ + /* We use the float versions of exp/log, since these functions are + significantly faster, and we really don't need much precision + here. The entropy contained in [next_mt_generate_geom] is anyway + bounded by the entropy provided by [mt_generate_uniform], which + is 32bits. */ + double res = 1 + logf(mt_generate_uniform()) * one_log1m_lambda; + if(res > Max_long) return Max_long; + return (uintnat)res; } -#define MAX_MT_GENERATE_POISSON (1<<29) -static double next_mt_generate_poisson; -/* Simulate a Poisson distribution of parameter [lambda*len]. The - result is clipped to the interval [0..MAX_MT_GENERATE_POISSON] */ -static int32_t mt_generate_poisson(double len) -{ - double cur_lambda = lambda * len; - CAMLassert(cur_lambda >= 0 && cur_lambda < 1e20); - - if(cur_lambda < 20) { - /* First algorithm when [cur_lambda] is small: we proceed by - repeated simulations of exponential distributions. */ - - next_mt_generate_poisson -= cur_lambda; - if(next_mt_generate_poisson > 0) { - /* Fast path if [cur_lambda] is small: we reuse the same - exponential sample across several calls to - [mt_generate_poisson]. */ - return 0; - } else { - /* We use the float versions of exp/log, since these functions - are significantly faster, and we really don't need much - precision here. The entropy contained in - [next_mt_generate_poisson] is anyway bounded by the entropy - provided by [mt_generate_uniform], which is 32bits. */ - double p = expf(-next_mt_generate_poisson); - int32_t k = 0; - do { - k++; - p *= mt_generate_uniform(); - } while(p > 1); - - /* [p] is now uniformly distributed in [0, 1] and independent - from other variables (including [k]). We can therefore reuse - [p] for reinitializing [next_mt_generate_poisson]. */ - next_mt_generate_poisson = -logf(p); - - return k; - } +static uintnat next_mt_generate_binom; +/* Simulate a binomial variable of parameters [len] and [lambda]. + This sampling algorithm has running time linear with [len * + lambda]. We could use more a involved algorithm, but this should + be good enough since, in the average use case, [lambda] <= 0.01 and + therefore the generation of the binomial variable is amortized by + the initialialization of the corresponding block. - } else { - /* Second algorithm when [cur_lambda] is large. Taken from: */ - /* The Computer Generation of Poisson Random Variables - A. C. Atkinson Journal of the Royal Statistical Society. - Series C (Applied Statistics) Vol. 28, No. 1 (1979), pp. 29-35 - "Method PA" */ - - double c, beta_inverse, k, log_cur_lambda; - log_cur_lambda = log(cur_lambda); - c = 0.767 - 3.36/cur_lambda; - beta_inverse = sqrt(0.30396355092701332623 * cur_lambda); - /* ^ = 3./(PI*PI) */ - k = log(c*beta_inverse) - cur_lambda; - while(1) { - double u, n, v, y; - u = mt_generate_uniform(); - y = log(1./u-1); - n = floor(cur_lambda - y*beta_inverse + 0.5); - if(n < 0.) - continue; - v = mt_generate_uniform(); - /* When [cur_lambda] is large, we expect [n*log_cur_lambda] and - [lfact(n)] to be close, while both being relatively - large. Hence, here, we may actually need the double precision - in the computation of log and lfact. */ - if(y + log(v*u*u) < k + n*log_cur_lambda - lfact(n)) - return n > MAX_MT_GENERATE_POISSON ? MAX_MT_GENERATE_POISSON : n; - } - } + If needed, we could use algorithm BTRS from the paper: + Hormann, Wolfgang. "The generation of binomial random variates." + Journal of statistical computation and simulation 46.1-2 (1993), pp101-110. + + Requires [lambda > 0] and [len < Max_long]. + */ +static uintnat mt_generate_binom(uintnat len) +{ + uintnat res; + for(res = 0; next_mt_generate_binom < len; res++) + next_mt_generate_binom += mt_generate_geom(); + next_mt_generate_binom -= len; + return res; } /**** Interface with the OCaml code. ****/ @@ -186,7 +133,7 @@ CAMLprim value caml_memprof_set(value v) double l = Double_val(Field(v, 0)); intnat sz = Long_val(Field(v, 1)); - if(sz < 0 || !(l >= 0.) || l > 1.) + if(sz < 0 || !(l >= 0.) || l > 1.) /* Checks that [l] is not NAN. */ caml_invalid_argument("caml_memprof_set"); if(!init) { @@ -199,14 +146,18 @@ CAMLprim value caml_memprof_set(value v) mt_state[i] = 0x6c078965 * (mt_state[i-1] ^ (mt_state[i-1] >> 30)) + i; caml_register_generational_global_root(&memprof_callback); - - next_mt_generate_poisson = -logf(mt_generate_uniform()); } lambda = l; - lambda_inverse = 1/l; + if(l > 0) { + one_log1m_lambda = l == 1 ? 0 : 1/caml_log1p(-l); + next_mt_generate_binom = mt_generate_geom(); + } + caml_memprof_renew_minor_sample(); + callstack_size = sz; + caml_modify_generational_global_root(&memprof_callback, Field(v, 2)); CAMLreturn(Val_unit); @@ -219,7 +170,7 @@ enum ml_alloc_kind { Serialized = Val_long(2) }; -static value do_callback(tag_t tag, intnat wosize, int32_t occurrences, +static value do_callback(tag_t tag, uintnat wosize, uintnat occurrences, value callstack, enum ml_alloc_kind cb_kind) { CAMLparam1(callstack); CAMLlocal1(sample_info); @@ -240,18 +191,18 @@ static value do_callback(tag_t tag, intnat wosize, int32_t occurrences, static value capture_callstack_major() { value res; - intnat wosize = caml_current_callstack_size(callstack_size); + uintnat wosize = caml_current_callstack_size(callstack_size); /* We do not use [caml_alloc] to make sure the GC will not get called. */ if(wosize == 0) return Atom (0); - res = caml_alloc_shr_no_track(wosize, 0); - caml_current_callstack_write(res); + res = caml_alloc_shr_no_track_noexc(wosize, 0); + if(res != 0) caml_current_callstack_write(res); return res; } static value capture_callstack_minor() { value res; - intnat wosize = caml_current_callstack_size(callstack_size); + uintnat wosize = caml_current_callstack_size(callstack_size); CAMLassert(caml_memprof_suspended); /* => no samples in the call stack. */ res = caml_alloc(wosize, 0); caml_current_callstack_write(res); @@ -261,7 +212,7 @@ static value capture_callstack_minor() struct caml_memprof_postponed_block { value block; value callstack; - int32_t occurrences; + uintnat occurrences; struct caml_memprof_postponed_block* next; } *caml_memprof_postponed_head = NULL; @@ -272,17 +223,22 @@ struct caml_memprof_postponed_block { call is performed when possible. */ void caml_memprof_track_alloc_shr(value block) { - int32_t occurrences; + uintnat occurrences; CAMLassert(Is_in_heap(block)); /* This test also makes sure memprof is initialized. */ if(lambda == 0 || caml_memprof_suspended) return; - occurrences = mt_generate_poisson(Whsize_val(block)); + occurrences = mt_generate_binom(Whsize_val(block)); if(occurrences > 0) { + value callstack; struct caml_memprof_postponed_block* pb = caml_stat_alloc_noexc(sizeof(struct caml_memprof_postponed_block)); - value callstack = capture_callstack_major(); if(pb == NULL) return; + callstack = capture_callstack_major(); + if(callstack == 0) { + caml_stat_free(pb); + return; + } pb->block = block; caml_register_generational_global_root(&pb->block); pb->callstack = callstack; @@ -358,34 +314,21 @@ static void shift_sample(uintnat n) /* Renew the next sample in the minor heap. This needs to be called after each minor sampling and after each minor collection. In - practice, because we disable sampling during callbacks, this is - called at each sampling (including major ones). These extra calls - do not change the statistical properties of the sampling because of - the memorylessness of the exponential distribution. */ + practice, this is called at each sampling in the minor heap and at + each minor collection. Extra calls do not change the statistical + properties of the sampling because of the memorylessness of the + geometric distribution. */ void caml_memprof_renew_minor_sample(void) { - double exp; - uintnat max, exp_int; if(lambda == 0) /* No trigger in the current minor heap. */ caml_memprof_young_trigger = caml_young_alloc_start; else { - exp = - lambda_inverse * logf(mt_generate_uniform()); - max = caml_young_ptr - caml_young_alloc_start; - if(exp >= (double)max) /* No trigger in the current minor heap. */ + uintnat geom = mt_generate_geom(); + if(caml_young_ptr - caml_young_alloc_start < geom) + /* No trigger in the current minor heap. */ caml_memprof_young_trigger = caml_young_alloc_start; - else { - exp_int = (uintnat)exp; - /* This assertion can be false only if [max] is not exactly - representable as a double, which cannot happen if the size of the - minor heap does not reach 2^52. */ - CAMLassert(exp_int < max); - - caml_memprof_young_trigger = caml_young_ptr - exp_int; - - next_sample_frac_part = exp - exp_int; - CAMLassert(0 <= next_sample_frac_part && next_sample_frac_part < 1); - } + caml_memprof_young_trigger = caml_young_ptr - (geom - 1); } caml_update_young_limit(); @@ -399,8 +342,7 @@ void caml_memprof_track_young(tag_t tag, uintnat wosize) CAMLparam0(); CAMLlocal2(ephe, callstack); uintnat whsize = Whsize_wosize(wosize); - double rest; - int32_t occurrences; + uintnat occurrences; if(caml_memprof_suspended) { caml_memprof_renew_minor_sample(); @@ -408,7 +350,7 @@ void caml_memprof_track_young(tag_t tag, uintnat wosize) } /* If [lambda == 0], then [caml_memprof_young_trigger] should be - equal to [caml_young_alloc_start]. But this function is only + equal to [caml_young_alloc_start]. But this function is only called with [caml_young_alloc_start <= caml_young_ptr < caml_memprof_young_trigger], which is contradictory. */ CAMLassert(lambda > 0); @@ -420,11 +362,8 @@ void caml_memprof_track_young(tag_t tag, uintnat wosize) call the callback and use as a sample the block which will be allocated right after the callback. */ - /* [rest] is the size of the part of the allocated block which is - after the sampling point. */ - rest = (caml_memprof_young_trigger - caml_young_ptr) - next_sample_frac_part; - CAMLassert(rest >= 0); - occurrences = mt_generate_poisson(rest) + 1; + occurrences = + mt_generate_binom(caml_memprof_young_trigger - 1 - caml_young_ptr) + 1; /* Restore the minor heap in a valid state and suspend sampling for calling the callback. diff --git a/runtime/signals_nat.c b/runtime/signals_nat.c index 42224b6854..ce05dff35c 100644 --- a/runtime/signals_nat.c +++ b/runtime/signals_nat.c @@ -77,7 +77,13 @@ void caml_garbage_collection(void) /* TEMPORARY: if we have just sampled an allocation in native mode, we simply renew the sample to ignore it. Otherwise, renewing now will not have any effect on the sampling distribution, because of - the memorylessness of the Poisson process. */ + the memorylessness of the Bernoulli process. + + FIXME: if the sampling rate is 1, this leads to infinite loop, + because we are using a binomial distribution in [memprof.c]. This + will go away when the sampling of natively allocated blocks will + be correctly implemented. + */ caml_memprof_renew_minor_sample(); if (caml_requested_major_slice || caml_requested_minor_gc || caml_young_ptr - caml_young_trigger < Max_young_whsize){ diff --git a/stdlib/gc.mli b/stdlib/gc.mli index 9242033a0f..2de9a5d8ee 100644 --- a/stdlib/gc.mli +++ b/stdlib/gc.mli @@ -387,14 +387,15 @@ val delete_alarm : alarm -> unit (** [delete_alarm a] will stop the calls to the function associated to [a]. Calling [delete_alarm a] again has no effect. *) -(** [Memprof] is a sampling engine for allocated words. The blocks - are sampled according to a Poisson process. That is, every block - has a probability of being sampled which is proportional to its - size, and large blocks can be sampled several times. The samples - appear using a configurable sampling rate. - - This engine is typically used by a statistical memory profiler. - *) +(** [Memprof] is a sampling engine for allocated memory words. Every + allocated word has a probability of being sampled equal to a + configurable sampling rate. Since blocks are composed of several + words, a block can potentially be sampled several times. When a + block is sampled (i.e., it contains at least one sample word), a + user-defined callback is called. + + This engine makes it possible to implement a low-overhead memory + profiler as an OCaml library. *) module Memprof : sig type alloc_kind = @@ -409,10 +410,11 @@ module Memprof : type sample_info = { n_samples: int; - (** The number of samples in this block. Always >= 1, it is sampled - according to a Poisson process, and in average equal to the - size of the block (including the header) multiplied by lambda - (the sampling rate). *) + (** The number of samples in this block. Always >= 1, it is + sampled according to a binomial distribution whose + parameters are the size of the block (including the header) + and the sampling rate. Hence, it is in average equal to the + size of the block multiplied by the sampling rate. *) kind: alloc_kind; (** The kind of the allocation. *) tag: int; @@ -446,9 +448,9 @@ module Memprof : type 'a ctrl = { sampling_rate : float; (** The sampling rate in samples per word (including headers). - Usually, with cheap callbacks, a rate of 0.001 has no - visible effect on performance, and 0.01 causes the program - to run a few percent slower. *) + Usually, with cheap callbacks, a rate of 0.001 has no + visible effect on performance, and 0.01 causes the program + to run a few percent slower. *) callstack_size : int; (** The length of the callstack recorded at every sample. *) callback : 'a callback diff --git a/testsuite/tests/statmemprof/arrays_in_major.byte.reference b/testsuite/tests/statmemprof/arrays_in_major.byte.reference index 26f7865568..4f74573d0d 100644 --- a/testsuite/tests/statmemprof/arrays_in_major.byte.reference +++ b/testsuite/tests/statmemprof/arrays_in_major.byte.reference @@ -1,13 +1,13 @@ check_nosample check_ephe_full_major check_no_nested -check_distrib 300 3000 1 0.000010 +check_distrib 300 3000 3 0.000010 check_distrib 300 3000 1 0.000100 check_distrib 300 3000 1 0.010000 -check_distrib 300 3000 1 1.000000 +check_distrib 300 3000 1 0.900000 check_distrib 300 300 100000 0.100000 check_distrib 300000 300000 30 0.100000 check_callstack -Raised by primitive operation at file "arrays_in_major.ml", line 136, characters 2-35 -Called from file "arrays_in_major.ml", line 142, characters 9-27 +Raised by primitive operation at file "arrays_in_major.ml", line 147, characters 2-35 +Called from file "arrays_in_major.ml", line 153, characters 9-27 OK ! diff --git a/testsuite/tests/statmemprof/arrays_in_major.ml b/testsuite/tests/statmemprof/arrays_in_major.ml index c757d503dd..adb20bae2e 100644 --- a/testsuite/tests/statmemprof/arrays_in_major.ml +++ b/testsuite/tests/statmemprof/arrays_in_major.ml @@ -58,7 +58,11 @@ let check_no_nested () = Printf.printf "check_no_nested\n%!"; let in_callback = ref false in start { - sampling_rate = 1.; + (* FIXME: we should use 1. to make sure the block is sampled, + but the runtime does an infinite loop in native mode in this + case. This bug will go away when the sampling of natively + allocated will be correctly implemented. *) + sampling_rate = 0.5; callstack_size = 10; callback = fun _ -> assert (not !in_callback); @@ -92,22 +96,25 @@ let check_distrib lo hi cnt rate = stop (); (* The probability distribution of the number of samples follows a - poisson distribution with mean tot_alloc*rate. Given that we - expect this quantity to be large (i.e., > 100), this distribution - is approximately equal to a normal distribution. We compute a - 1e-8 confidence interval for !smp using quantiles of the normal - distribution, and check that we are in this confidence interval. *) + binomial distribution of parameters tot_alloc and rate. Given + that tot_alloc*rate and tot_alloc*(1-rate) are large (i.e., > + 100), this distribution is approximately equal to a normal + distribution. We compute a 1e-8 confidence interval for !smp + using quantiles of the normal distribution, and check that we are + in this confidence interval. *) let tot_alloc = cnt*(lo+hi+2)*(hi-lo+1)/2 in + assert (float tot_alloc *. rate > 100. && + float tot_alloc *. (1. -. rate) > 100.); let mean = float tot_alloc *. rate in - let stddev = sqrt mean in + let stddev = sqrt (float tot_alloc *. rate *. (1. -. rate)) in (* This assertion has probability to fail close to 1e-8. *) assert (abs_float (mean -. float !smp) <= stddev *. 5.7) let () = - check_distrib 300 3000 1 0.00001; + check_distrib 300 3000 3 0.00001; check_distrib 300 3000 1 0.0001; check_distrib 300 3000 1 0.01; - check_distrib 300 3000 1 1.; + check_distrib 300 3000 1 0.9; check_distrib 300 300 100000 0.1; check_distrib 300000 300000 30 0.1 @@ -127,7 +134,11 @@ let[@inline never] check_callstack () = Printf.printf "check_callstack\n%!"; let callstack = ref None in start { - sampling_rate = 1.; + (* FIXME: we should use 1. to make sure the block is sampled, + but the runtime does an infinite loop in native mode in this + case. This bug will go away when the sampling of natively + allocated will be correctly implemented. *) + sampling_rate = 0.5; callstack_size = 10; callback = fun info -> if info.kind = Major then callstack := Some info.callstack; diff --git a/testsuite/tests/statmemprof/arrays_in_major.opt.reference b/testsuite/tests/statmemprof/arrays_in_major.opt.reference index 464f0d5b52..36d45330b2 100644 --- a/testsuite/tests/statmemprof/arrays_in_major.opt.reference +++ b/testsuite/tests/statmemprof/arrays_in_major.opt.reference @@ -1,14 +1,14 @@ check_nosample check_ephe_full_major check_no_nested -check_distrib 300 3000 1 0.000010 +check_distrib 300 3000 3 0.000010 check_distrib 300 3000 1 0.000100 check_distrib 300 3000 1 0.010000 -check_distrib 300 3000 1 1.000000 +check_distrib 300 3000 1 0.900000 check_distrib 300 300 100000 0.100000 check_distrib 300000 300000 30 0.100000 check_callstack Raised by primitive operation at file "arrays_in_major.ml", line 17, characters 14-28 -Called from file "arrays_in_major.ml", line 136, characters 2-35 -Called from file "arrays_in_major.ml", line 142, characters 9-27 +Called from file "arrays_in_major.ml", line 147, characters 2-35 +Called from file "arrays_in_major.ml", line 153, characters 9-27 OK ! diff --git a/testsuite/tests/statmemprof/arrays_in_minor.byte.reference b/testsuite/tests/statmemprof/arrays_in_minor.byte.reference index 64149f8b0e..183af7bbf9 100644 --- a/testsuite/tests/statmemprof/arrays_in_minor.byte.reference +++ b/testsuite/tests/statmemprof/arrays_in_minor.byte.reference @@ -4,10 +4,10 @@ check_no_nested check_distrib 1 250 1000 0.000010 check_distrib 1 250 1000 0.000100 check_distrib 1 250 1000 0.010000 -check_distrib 1 250 1000 1.000000 +check_distrib 1 250 1000 0.900000 check_distrib 1 1 10000000 0.010000 check_distrib 250 250 100000 0.100000 check_callstack -Raised by primitive operation at file "arrays_in_minor.ml", line 142, characters 2-35 -Called from file "arrays_in_minor.ml", line 148, characters 9-27 +Raised by primitive operation at file "arrays_in_minor.ml", line 153, characters 2-35 +Called from file "arrays_in_minor.ml", line 159, characters 9-27 OK ! diff --git a/testsuite/tests/statmemprof/arrays_in_minor.ml b/testsuite/tests/statmemprof/arrays_in_minor.ml index aa275e103d..fa8b26ecfa 100644 --- a/testsuite/tests/statmemprof/arrays_in_minor.ml +++ b/testsuite/tests/statmemprof/arrays_in_minor.ml @@ -63,7 +63,11 @@ let check_no_nested () = Printf.printf "check_no_nested\n%!"; let in_callback = ref false in start { - sampling_rate = 1.; + (* FIXME: we should use 1. to make sure the block is sampled, + but the runtime does an infinite loop in native mode in this + case. This bug will go away when the sampling of natively + allocated will be correctly implemented. *) + sampling_rate = 0.5; callstack_size = 10; callback = fun _ -> assert (not !in_callback); @@ -98,14 +102,17 @@ let check_distrib lo hi cnt rate = stop (); (* The probability distribution of the number of samples follows a - poisson distribution with mean tot_alloc*rate. Given that we - expect this quantity to be large (i.e., > 100), this distribution - is approximately equal to a normal distribution. We compute a - 1e-8 confidence interval for !smp using quantiles of the normal - distribution, and check that we are in this confidence interval. *) + binomial distribution of parameters tot_alloc and rate. Given + that tot_alloc*rate and tot_alloc*(1-rate) are large (i.e., > + 100), this distribution is approximately equal to a normal + distribution. We compute a 1e-8 confidence interval for !smp + using quantiles of the normal distribution, and check that we are + in this confidence interval. *) let tot_alloc = cnt*(lo+hi+2)*(hi-lo+1)/2 in + assert (float tot_alloc *. rate > 100. && + float tot_alloc *. (1. -. rate) > 100.); let mean = float tot_alloc *. rate in - let stddev = sqrt mean in + let stddev = sqrt (float tot_alloc *. rate *. (1. -. rate)) in (* This assertion has probability to fail close to 1e-8. *) assert (abs_float (mean -. float !smp) <= stddev *. 5.7) @@ -113,7 +120,7 @@ let () = check_distrib 1 250 1000 0.00001; check_distrib 1 250 1000 0.0001; check_distrib 1 250 1000 0.01; - check_distrib 1 250 1000 1.; + check_distrib 1 250 1000 0.9; check_distrib 1 1 10000000 0.01; check_distrib 250 250 100000 0.1 @@ -133,7 +140,11 @@ let[@inline never] check_callstack () = Printf.printf "check_callstack\n%!"; let callstack = ref None in start { - sampling_rate = 1.; + (* FIXME: we should use 1. to make sure the block is sampled, + but the runtime does an infinite loop in native mode in this + case. This bug will go away when the sampling of natively + allocated will be correctly implemented. *) + sampling_rate = 0.5; callstack_size = 10; callback = fun info -> if info.tag = 0 then callstack := Some info.callstack; diff --git a/testsuite/tests/statmemprof/arrays_in_minor.opt.reference b/testsuite/tests/statmemprof/arrays_in_minor.opt.reference index d2d95bf2ef..e62709ca30 100644 --- a/testsuite/tests/statmemprof/arrays_in_minor.opt.reference +++ b/testsuite/tests/statmemprof/arrays_in_minor.opt.reference @@ -4,11 +4,11 @@ check_no_nested check_distrib 1 250 1000 0.000010 check_distrib 1 250 1000 0.000100 check_distrib 1 250 1000 0.010000 -check_distrib 1 250 1000 1.000000 +check_distrib 1 250 1000 0.900000 check_distrib 1 1 10000000 0.010000 check_distrib 250 250 100000 0.100000 check_callstack Raised by primitive operation at file "arrays_in_minor.ml", line 22, characters 20-34 -Called from file "arrays_in_minor.ml", line 142, characters 2-35 -Called from file "arrays_in_minor.ml", line 148, characters 9-27 +Called from file "arrays_in_minor.ml", line 153, characters 2-35 +Called from file "arrays_in_minor.ml", line 159, characters 9-27 OK ! diff --git a/testsuite/tests/statmemprof/exception_callback.ml b/testsuite/tests/statmemprof/exception_callback.ml index 750a8e9c4d..a490c0f2aa 100644 --- a/testsuite/tests/statmemprof/exception_callback.ml +++ b/testsuite/tests/statmemprof/exception_callback.ml @@ -12,7 +12,11 @@ let _ = Printexc.record_backtrace false let _ = start { - sampling_rate = 1.; + (* FIXME: we should use 1. to make sure the block is sampled, + but the runtime does an infinite loop in native mode in this + case. This bug will go away when the sampling of natively + allocated will be correctly implemented. *) + sampling_rate = 0.5; callstack_size = 10; callback = fun _ -> assert false }; diff --git a/testsuite/tests/statmemprof/exception_callback.reference b/testsuite/tests/statmemprof/exception_callback.reference index 361b2d71e6..3c141ac1e9 100644 --- a/testsuite/tests/statmemprof/exception_callback.reference +++ b/testsuite/tests/statmemprof/exception_callback.reference @@ -1 +1 @@ -Fatal error: exception File "exception_callback.ml", line 17, characters 24-30: Assertion failed +Fatal error: exception File "exception_callback.ml", line 21, characters 24-30: Assertion failed diff --git a/testsuite/tests/statmemprof/lists_in_minor.byte.reference b/testsuite/tests/statmemprof/lists_in_minor.byte.reference index e769d0b888..68bfe388e0 100644 --- a/testsuite/tests/statmemprof/lists_in_minor.byte.reference +++ b/testsuite/tests/statmemprof/lists_in_minor.byte.reference @@ -4,9 +4,9 @@ check_distrib 1000000 10 0.000100 check_distrib 1000000 10 0.001000 check_distrib 1000000 10 0.010000 check_distrib 100000 10 0.100000 -check_distrib 100000 10 1.000000 +check_distrib 100000 10 0.900000 check_callstack Raised by primitive operation at file "lists_in_minor.ml", line 15, characters 11-33 -Called from file "lists_in_minor.ml", line 67, characters 2-26 -Called from file "lists_in_minor.ml", line 74, characters 2-20 +Called from file "lists_in_minor.ml", line 70, characters 2-26 +Called from file "lists_in_minor.ml", line 77, characters 2-20 OK ! diff --git a/testsuite/tests/statmemprof/lists_in_minor.ml b/testsuite/tests/statmemprof/lists_in_minor.ml index 416b520aac..d28ecbe117 100644 --- a/testsuite/tests/statmemprof/lists_in_minor.ml +++ b/testsuite/tests/statmemprof/lists_in_minor.ml @@ -34,14 +34,17 @@ let check_distrib len cnt rate = stop (); (* The probability distribution of the number of samples follows a - poisson distribution with mean tot_alloc*rate. Given that we - expect this quantity to be large (i.e., > 100), this distribution - is approximately equal to a normal distribution. We compute a - 1e-8 confidence interval for !smp using quantiles of the normal - distribution, and check that we are in this confidence interval. *) + binomial distribution of parameters tot_alloc and rate. Given + that tot_alloc*rate and tot_alloc*(1-rate) are large (i.e., > + 100), this distribution is approximately equal to a normal + distribution. We compute a 1e-8 confidence interval for !smp + using quantiles of the normal distribution, and check that we are + in this confidence interval. *) let tot_alloc = cnt*len*3 in + assert (float tot_alloc *. rate > 100. && + float tot_alloc *. (1. -. rate) > 100.); let mean = float tot_alloc *. rate in - let stddev = sqrt mean in + let stddev = sqrt (float tot_alloc *. rate *. (1. -. rate)) in (* This assertion has probability to fail close to 1e-8. *) assert (abs_float (mean -. float !smp) <= stddev *. 5.7) @@ -52,7 +55,7 @@ let () = check_distrib 1000000 10 0.001; check_distrib 1000000 10 0.01; check_distrib 100000 10 0.1; - check_distrib 100000 10 1. + check_distrib 100000 10 0.9 let[@inline never] check_callstack () = Printf.printf "check_callstack\n%!"; |