Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch the default allocation policy to best-fit. #10188

Merged
merged 4 commits into from
Feb 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ Working version
- #10136: Minor clean-ups in runtime/io.c and runtime/caml/io.h
(Xavier Leroy, review by David Allsopp and Guillaume Munch-Maccagnoni)

- #10188: Switch the default allocation policy to best-fit and adjust the
default overhead parameter accordingly.
(Damien Doligez, review by Josh Berdine and Xavier Leroy)

### Code generation and optimizations:

- #9876: do not cache the young_limit GC variable in a processor register.
Expand Down
3 changes: 1 addition & 2 deletions man/ocamlrun.m
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ The initial size of the major heap (in words).
.BR a \ (allocation_policy)
The policy used for allocating in the OCaml heap. Possible values
are 0 for the next-fit policy, 1 for the first-fit
policy, and 2 for the best-fit policy. Best-fit is still experimental,
but probably the best of the three. The default is 0.
policy, and 2 for the best-fit policy. The default is 2.
See the Gc module documentation for details.
.TP
.BR s \ (minor_heap_size)
Expand Down
3 changes: 1 addition & 2 deletions manual/src/cmds/runtime.etex
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ The following environment variables are also consulted:
\item[a] ("allocation_policy")
The policy used for allocating in the OCaml heap. Possible values
are "0" for the next-fit policy, "1" for the first-fit
policy, and "2" for the best-fit policy. Best-fit is still experimental,
but probably the best of the three. The default is "0" (next-fit).
policy, and "2" for the best-fit policy. The default is "2" (best-fit).
See the Gc module documentation for details.
\item[s] ("minor_heap_size") Size of the minor heap. (in words)
\item[i] ("major_heap_increment") Default size increment for the
Expand Down
2 changes: 1 addition & 1 deletion runtime/caml/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ typedef uint64_t uintnat;
/* Default speed setting for the major GC. The heap will grow until
the dead objects and the free list represent this percentage of the
total size of live objects. */
#define Percent_free_def 80
#define Percent_free_def 120

/* Default setting for the compacter: 500%
(i.e. trigger the compacter when 5/6 of the heap is free or garbage)
Expand Down
2 changes: 1 addition & 1 deletion runtime/freelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -1754,7 +1754,7 @@ enum {
policy_best_fit = 2,
};

uintnat caml_allocation_policy = policy_next_fit;
uintnat caml_allocation_policy = policy_best_fit;

/********************* exported functions *****************************/

Expand Down
21 changes: 7 additions & 14 deletions stdlib/gc.mli
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ type control =
percentage of the memory used for live data.
The GC will work more (use more CPU time and collect
blocks more eagerly) if [space_overhead] is smaller.
Default: 80. *)
Default: 100. *)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also be changed from 100 to 120? @damiendoligez?


mutable verbose : int;
[@ocaml.deprecated_mutable "Use {(Gc.get()) with Gc.verbose = ...}"]
Expand Down Expand Up @@ -164,30 +164,23 @@ type control =
memory than both next-fit and first-fit.
(since OCaml 4.10)

The current default is next-fit, as the best-fit policy is new
and not yet widely tested. We expect best-fit to become the
default in the future.
The default is best-fit.

On one example that was known to be bad for next-fit and first-fit,
next-fit takes 28s using 855Mio of memory,
first-fit takes 47s using 566Mio of memory,
best-fit takes 27s using 545Mio of memory.

Note: When changing to a low-fragmentation policy, you may
need to augment the [space_overhead] setting, for example
using [100] instead of the default [80] which is tuned for
next-fit. Indeed, the difference in fragmentation behavior
means that different policies will have different proportion
of "wasted space" for a given program. Less fragmentation
means a smaller heap so, for the same amount of wasted space,
a higher proportion of wasted space. This makes the GC work
harder, unless you relax it by increasing [space_overhead].
Note: If you change to next-fit, you may need to reduce
the [space_overhead] setting, for example using [80] instead
of the default [100] which is tuned for best-fit. Otherwise,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this

your program will need more memory.

Note: changing the allocation policy at run-time forces
a heap compaction, which is a lengthy operation unless the
heap is small (e.g. at the start of the program).

Default: 0.
Default: 2.

@since 3.11.0 *)

Expand Down