Revision: 54543
http://brlcad.svn.sourceforge.net/brlcad/?rev=54543&view=rev
Author: brlcad
Date: 2013-03-06 22:24:48 +0000 (Wed, 06 Mar 2013)
Log Message:
-----------
stub in an initial implementation of a really fast heap-based memory allocation
capability for small allocation sizes. it allocates size-designated blocks of
memory ('pages') in order to substantially reduce calls to system malloc. it
has a nice property of being O(1) on alloc and profiles substantially faster
than system malloc. from half to several orders of magnitude in testing
(making the call cost near-zero). presently only implemented for byte sizes 1
through 64 (trivial to extend). implementation of free is stubbed empty, but
intend to reuse free cells and reclaim memory on-demand. made to match
BU_GET/BU_PUT so it can serve as the back-end implementation.
Added Paths:
-----------
brlcad/trunk/src/libbu/heap.c
Added: brlcad/trunk/src/libbu/heap.c
===================================================================
--- brlcad/trunk/src/libbu/heap.c (rev 0)
+++ brlcad/trunk/src/libbu/heap.c 2013-03-06 22:24:48 UTC (rev 54543)
@@ -0,0 +1,199 @@
+/* H E A P . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2013 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file heap.c
+ *
+ * Brief description
+ *
+ */
+
+#include "common.h"
+
+#include "bu.h"
+
+
+#define BINS 64
+#define PAGESIZE (BINS * 1024)
+
+/** heaps is an array of lists containing pages of memory binned per requested
allocation size */
+static char **heaps[BINS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+/** pages is an array of counts for how many heap pages have been allocated
per each heaps[] size */
+static size_t pages[BINS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+/** used is an array of lists to count how much memory has been used
(allocated) per page */
+static size_t *used[BINS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+static size_t alloc[BINS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static size_t misses = 0;
+
+
+void
+bu_heap_print()
+{
+ size_t i, j;
+ size_t allocations = 0;
+ size_t total_pages = 0;
+
+ bu_log("=======================\n"
+ "Memory Heap Information\n"
+ "-----------------------\n");
+
+ for (i=0; i < BINS; i++) {
+ allocations = 0;
+ for (j=0; j < pages[i]; j++) {
+ allocations += used[i][j] / (i+1);
+ }
+ if (allocations > 0)
+ bu_log("%04ld [%02ld] => %ld\n", i, pages[i], allocations);
+ total_pages += pages[i];
+ }
+ bu_log("-----------------------\n"
+ "size [pages] => allocs\n"
+ "Heap range: 1-%ld bytes\n"
+ "Page size: %ld bytes\n"
+ "Pages: %ld (%.2lfMB)\n"
+ "=======================\n", BINS, PAGESIZE, total_pages,
(double)(total_pages * PAGESIZE) / (1024.0*1024.0));
+}
+
+
+void *
+bu_heap_get(size_t sz)
+{
+ char *ret;
+ register size_t smo = sz-1;
+ static int printit = 0;
+
+ if (sz > BINS || sz == 0) {
+ misses++;
+ return bu_calloc(1, sz, "heap calloc");
+ }
+
+ alloc[smo]++;
+
+ /* init */
+ if (!pages[smo]) {
+
+ if (printit==0) {
+ atexit(bu_heap_print);
+ printit++;
+ }
+
+ pages[smo]++;
+ heaps[smo] = (char **)bu_malloc(1 * sizeof(char *), "heap malloc
heaps[]");
+ heaps[smo][0] = (char *)bu_calloc(1, PAGESIZE, "heap calloc
heaps[][0]");
+ used[smo] = (size_t *)bu_malloc(1 * sizeof(size_t), "heap malloc
used[]");
+ used[smo][0] = 0;
+ }
+
+ /* grow */
+ if (used[smo][pages[smo]-1]+sz > PAGESIZE) {
+ pages[smo]++;
+ heaps[smo] = (char **)bu_realloc(heaps[smo], pages[smo] * sizeof(char
*), "heap realloc heaps[]");
+ heaps[smo][pages[smo]-1] = (char *)bu_calloc(1, PAGESIZE, "heap calloc
heaps[][]");
+ used[smo] = (size_t *)bu_realloc(used[smo], pages[smo] *
sizeof(size_t), "heap realloc used[]");
+ used[smo][pages[smo]-1] = 0;
+ }
+
+ /* give */
+ ret = &(heaps[smo][pages[smo]-1][used[smo][pages[smo]-1]]);
+ used[smo][pages[smo]-1] += sz;
+
+ return (void *)ret;
+}
+
+
+void
+bu_heap_put(void *ptr, size_t sz)
+{
+ if (sz > BINS || sz == 0) {
+ bu_free(ptr, "heap free");
+ return;
+ }
+
+ return;
+}
+
+
+/* test driver application, intended to become part of unit test */
+#if 0
+
+int main (int ac, char *av[])
+{
+ int i;
+ void *ptr;
+ size_t allocalls = 0;
+ size_t freecalls = 0;
+
+ srand(time(0));
+
+ for (i=0; i<1024*1024*50; i++) {
+ size_t sz = (((double)rand() / (double)(RAND_MAX-1)) * (double)BINS) +
1;
+ printf("allocating %d: %ld\n", i, sz);
+#ifdef USE_MALLOC
+ ptr = malloc(sz);
+#else
+ ptr = bu_fastalloc(sz);
+#endif
+ allocalls++;
+
+ if (i%3==0) {
+ printf("freeing sz=%ld allocation\n", sz);
+#ifdef USE_MALLOC
+ free(ptr);
+#else
+ bu_fastfree(ptr);
+#endif
+ freecalls++;
+ }
+ if (i % (1024 * 1024) == 0) {
+#ifdef USE_MALLOC
+ free(NULL);
+#else
+ bu_fastfree(NULL);
+#endif
+ freecalls++;
+ }
+
+ }
+
+#ifdef USE_MALLOC
+ free(NULL);
+#else
+ bu_fastfree(NULL);
+#endif
+ freecalls++;
+
+ printf("calls: %ld, free: %ld\n", allocalls, freecalls);
+
+ return 0;
+}
+
+
+#endif
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * mode: C
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Property changes on: brlcad/trunk/src/libbu/heap.c
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits