[m-dev.] FYI: cell cache
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Sep 29 20:48:01 AEDT 2000
On 28-Sep-2000, Peter Ross <petdr at miscrit.be> wrote:
> + ( { CanCGC = yes } ->
> + ml_gen_var(Var, VarLval),
> + { String = string__format("MR_cache_cell(%d, MR_strip_tag(",
I would suggest spelling that as `MR_compile_time_GC'
rather than `MR_cache_cell'.
The you can do
#if defined(MR_COMPILE_TIME_GC)
#define MR_compile_time_GC(ptr) MR_GC_free(ptr)
#elif defined(MR_USE_CELL_CACHE)
#define MR_compile_time_GC(ptr) MR_cache_cell(ptr)
#else
#define MR_compile_time_GC(ptr) ((void)0)
#endif
> +++ compiler/mlds_to_c.m 2000/09/28 14:11:06
> @@ -2201,6 +2201,17 @@
>
> mlds_indent(Context, Indent + 1),
> mlds_output_lval(Target),
> + io__write_string(" = MR_get_cached_cell("),
> + io__write_int(list__length(Args)),
> + io__write_string(");\n"),
> + mlds_indent(Context, Indent + 1),
> + io__write_string("if ("),
> + mlds_output_lval(Target),
> + io__write_string(" == (MR_Word) NULL) {\n"),
> +
> + mlds_indent(Context, Indent + 2),
> + mlds_output_lval(Target),
Won't that code do the wrong thing in the case when the pointer tag on
the data you're allocating is supposed to be non-zero?
I think that if you get a cache hit, you never set the tag.
Anyway, rather than putting that code here, you could put
it inside MR_new_object().
> Index: runtime/mercury_memory.c
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/runtime/mercury_memory.c,v
> retrieving revision 1.19.4.1
> diff -u -r1.19.4.1 mercury_memory.c
> --- runtime/mercury_memory.c 2000/09/25 17:09:11 1.19.4.1
> +++ runtime/mercury_memory.c 2000/09/28 14:11:12
> @@ -330,3 +330,77 @@
> }
>
> /*---------------------------------------------------------------------------*/
> +
> +/*
> +** Compile time garbage collection cache.
> +** When structure reuse infers that a cell dies and is available for reuse,
> +** we insert it into a cache of cells available for reuse. When allocating
> +** new memory first check if there is a cell already in the cache of the
> +** correct size and use that saving the cost of the GC.
> +**
> +** For an example of when this cache should be a win, just look at the
> +** following very common code.
> +**
> +** io__read_char(Result),
> +** {
> +** Result => ok(Char) % the ok(_) cell dies.
> +** ...,
> +** ;
> +** Result => eof,
> +** ...
> +** ...
> +** }
> +**
> +** The ok(_) cell is very short lived being generated inside
> +** io__read_char and almost always immediately dieing, now imagine if we
> +** read a few characters in a row, we are going to need to create a new
> +** ok(_) cell for the next character however there is already one in the
> +** cache and hey presto we have a win!
> +*/
> +#define MR_MAX_CACHED_CELL_SIZE 10
> +static void *MR_cell_cache[MR_MAX_CACHED_CELL_SIZE+1];
> +
> +void
> +MR_cell_cache_init(void)
> +{
> + int i;
> +
> + for(i = 0; i <= MR_MAX_CACHED_CELL_SIZE; i++) {
> + MR_cell_cache[i] = (MR_Word) NULL;
> + }
> +}
You don't actually need to initialize the cells to null --
the C standard guarantees that they will be initialized to null.
So you could just omit this function.
The cast to MR_Word here is not needed.
> +void *
> +MR_get_cached_cell(size_t size)
> +{
> + void *cell;
> +
> + /*
> + ** We never have to worry about the garbage collector freeing
> + ** the cached blocks because there is always at least one reference
> + ** to the cell from the cache!
> + */
> + if (size > MR_MAX_CACHED_CELL_SIZE) {
> + return (MR_Word) NULL;
> + } else {
> + cell = MR_cell_cache[size];
> + MR_cell_cache[size] = (MR_Word) NULL;
> + return cell;
> + }
> +}
The casts to MR_Word here are not needed.
> +++ runtime/mercury_wrapper.c 2000/09/28 14:11:15
> @@ -956,6 +956,7 @@
>
> for (repcounter = 0; repcounter < repeats; repcounter++) {
> #ifdef MR_HIGHLEVEL_CODE
> + MR_cell_cache_init();
> do_interpreter();
> #else
> debugmsg0("About to call engine\n");
That's not really the right place to call MR_cell_cache_init().
It should be called from mercury_init(), not mercury_runtime_main().
But as noted above you don't really need it anyway.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list