A magazine allocator is a concept taken from a paper I have read about
memory allocation.  The paper was a general purpose memory allocator,
but I have trimmed that notion down to a special purpose fixed-size
allocator.

The way it works is that it can be thought of a stack.  Need a new
memory item, item pointer is popped off stack.  If no stack entries are
available, allocate and increase the size of the magazine by 1.  To
free, add entry to current stack location. O1 frees, and o1 allocation
in event there is a preallocated memory area.

The reason this is necessary is in the general case of heavy messaging,
totemsrp and totempg malloc/free the same sized data structures over and
over but cap out at about 5-10mb of totemsrp ram.

As an example, with current trunk, malloc/free consumes 15% of the cpu
utilization of corosync when evsbench is run from 1 through 30k messages
(about 5 minutes of constant use) (this is only the corosync binary):
[r...@bench-01 exec]# more 30k-old
189007    3.5554  libc-2.5.so              free
58158     1.0940  libc-2.5.so              _int_free
229858    4.3238  libc-2.5.so              malloc
201412    3.7887  libc-2.5.so              _int_malloc
89276     1.6793  libc-2.5.so              malloc_consolidate
1        1.9e-05  libc-2.5.so              _int_realloc
1        1.9e-05  libc-2.5.so              calloc
1        1.9e-05  libc-2.5.so              realloc
        14.4398%

The prototype I am working on instead consumes about 1.3% (this is only
the corosync binary):
[r...@bench-01 exec]# more 30k-last
25332     0.4572  libtotem_pg.so.3.0.0     mag_alloc
12489     0.2254  libc-2.5.so              malloc
1496      0.0270  libc-2.5.so              _int_malloc
1117      0.0202  libtotem_pg.so.3.0.0     mag_alloc
20       3.6e-04  libc-2.5.so              realloc
13       2.3e-04  libc-2.5.so              malloc_consolidate
6        1.1e-04  libc-2.5.so              _int_realloc
1        1.8e-05  libc-2.5.so              calloc
18109     0.3268  libc-2.5.so              free
2503      0.0452  libc-2.5.so              _int_free
2308      0.0417  libtotem_pg.so.3.0.0     mag_free
1208      0.0218  libtotem_pg.so.3.0.0     mag_free

          1.3345%

Naturally throughput increases dramatically.

See attached header file for the first rough implementation of the mag
allocator.  The noinline stuff is so i can get valid oprofile traces but
other then that, the code is dead simple.

Regards
-steve

/*
 * Copyright (c) 2009 Red Hat, Inc.
 *
 * All rights reserved.
 *
 * Author: Steven Dake ([email protected])
 *
 * This software licensed under BSD license, the text of which follows:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name of the MontaVista Software, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef MAGALLOC_H_DEFINED
#define MAGALLOC_H_DEFINED

#include <config.h>

#include <stdlib.h>

struct magazine_db {
	int object_size;
	void **objects;
	unsigned int object_count;
	unsigned int object_position;
};

#define DECLARE_MAGAZINE(magazine_name,object_sz)	\
static struct magazine_db (magazine_name) = {		\
	.object_size = object_sz,			\
	.objects = NULL,				\
	.object_count = 0,				\
	.object_position = 0,				\
};							
	
__attribute__((noinline))static void *mag_alloc (struct magazine_db *db) {
	void *ptr;

	if (db->object_count == db->object_position) {
		db->object_count += 1;
		db->objects = realloc (db->objects, sizeof (void *) * db->object_count);
		db->objects[db->object_position] = malloc (db->object_size);
	}
	ptr = db->objects[db->object_position];
	db->object_position++;
	return (ptr);
}

__attribute__((noinline))static void mag_free (struct magazine_db *db, void *addr) {
	db->object_position--;
	db->objects[db->object_position] = addr;
}
#endif /* MAGALLOC_H_DEFINED */
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to