Revision: 54886
http://brlcad.svn.sourceforge.net/brlcad/?rev=54886&view=rev
Author: brlcad
Date: 2013-03-26 19:25:57 +0000 (Tue, 26 Mar 2013)
Log Message:
-----------
implement a per-cpu data structure so that we can support multithreaded memory
requests without pooching our data and without needing to acquire a
performance-killer semaphore lock. restructure the bin data into a single
struct container which should give better data coherence as well (but need to
verify).
Modified Paths:
--------------
brlcad/trunk/src/libbu/heap.c
Modified: brlcad/trunk/src/libbu/heap.c
===================================================================
--- brlcad/trunk/src/libbu/heap.c 2013-03-26 18:59:03 UTC (rev 54885)
+++ brlcad/trunk/src/libbu/heap.c 2013-03-26 19:25:57 UTC (rev 54886)
@@ -58,6 +58,7 @@
* \ \ \
* oo o oooo 'o' is a PAGESIZE allocation of memory
*/
+#if 0
static char **heaps[BINS] = {0};
/**
@@ -82,34 +83,48 @@
/** keep track of allocation sizes outside our supported range */
static size_t misses = 0;
-
-/* sanity */
-#if PAGESIZE < BINS
-# error "ERROR: heap page size cannot be smaller than bin size"
#endif
+struct bins {
+ char **heaps;
+ size_t pages;
+ size_t *used;
+ size_t alloc;
+};
+
+struct cpus {
+ struct bins *bin;
+ size_t misses;
+} *per_cpu = NULL;
+
+
void
bu_heap_print()
{
- size_t i, j;
+ size_t h, i, j;
+ size_t misses = 0;
size_t allocations = 0;
size_t total_pages = 0;
size_t total_alloc = 0;
+ size_t ncpu = bu_avail_cpus();
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);
+ for (h=0; h < ncpu; h++) {
+ for (i=0; i < BINS; i++) {
+ allocations = 0;
+ for (j=0; j < per_cpu[h].bin[i].pages; j++) {
+ allocations += per_cpu[h].bin[i].used[j] / (i+1);
+ }
+ if (allocations > 0)
+ bu_log("%04zd [%02zd] => %zd\n", i, per_cpu[h].bin[i].pages,
allocations);
+ total_pages += per_cpu[h].bin[i].pages;
+ total_alloc += allocations;
}
- if (allocations > 0)
- bu_log("%04zd [%02zd] => %zd\n", i, pages[i], allocations);
- total_pages += pages[i];
- total_alloc += allocations;
+ misses += per_cpu[h].misses;
}
bu_log("-----------------------\n"
"size [pages] => allocs\n"
@@ -127,9 +142,26 @@
char *ret;
register size_t smo = sz-1;
static int printit = 0;
+ int oncpu;
+ struct bins *bin;
+ /* init per-cpu structures */
+ if (!per_cpu) {
+ size_t i;
+ size_t ncpus = bu_avail_cpus();
+ per_cpu = bu_calloc(ncpus, sizeof(struct cpus), "struct cpus");
+ for (i=0; i<ncpus; i++)
+ per_cpu[i].bin = bu_calloc(BINS, sizeof(struct bins), "struct
bins");
+ }
+
+#if 0
+ oncpu = bu_parallel_id();
+#else
+ oncpu = 0;
+#endif
+
if (sz > BINS || sz == 0) {
- misses++;
+ per_cpu[oncpu].misses++;
if (bu_debug) {
bu_log("DEBUG: heap size %zd out of range\n", sz);
@@ -141,35 +173,38 @@
return bu_calloc(1, sz, "heap calloc");
}
- alloc[smo]++;
+ bin = &per_cpu[oncpu].bin[smo];
+ bin->alloc++;
+ /* alloc[smo]++; */
+
/* init */
- if (!pages[smo]) {
+ if (!bin->pages) {
if (bu_debug && 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;
+ bin->pages++;
+ bin->heaps = (char **)bu_malloc(1 * sizeof(char *), "heap malloc
heaps[]");
+ bin->heaps[0] = (char *)bu_calloc(1, PAGESIZE, "heap calloc
heaps[][0]");
+ bin->used = (size_t *)bu_malloc(1 * sizeof(size_t), "heap malloc
used[]");
+ bin->used[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;
+ if (bin->used[bin->pages-1]+sz > PAGESIZE) {
+ bin->pages++;
+ bin->heaps = (char **)bu_realloc(bin->heaps, bin->pages * sizeof(char
*), "heap realloc heaps[]");
+ bin->heaps[bin->pages-1] = (char *)bu_calloc(1, PAGESIZE, "heap calloc
heaps[][]");
+ bin->used = (size_t *)bu_realloc(bin->used, bin->pages *
sizeof(size_t), "heap realloc used[]");
+ bin->used[bin->pages-1] = 0;
}
/* give */
- ret = &(heaps[smo][pages[smo]-1][used[smo][pages[smo]-1]]);
- used[smo][pages[smo]-1] += sz;
+ ret = &(bin->heaps[bin->pages-1][bin->used[bin->pages-1]]);
+ bin->used[bin->pages-1] += sz;
return (void *)ret;
}
@@ -241,9 +276,15 @@
return 0;
}
+#endif
+
+/* sanity */
+#if PAGESIZE < BINS
+# error "ERROR: heap page size cannot be smaller than bin size"
#endif
+
/*
* Local Variables:
* tab-width: 8
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Own the Future-Intel® Level Up Game Demo Contest 2013
Rise to greatness in Intel's independent game demo contest.
Compete for recognition, cash, and the chance to get your game
on Steam. $5K grand prize plus 10 genre and skill prizes.
Submit your demo by 6/6/13. http://p.sf.net/sfu/intel_levelupd2d
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits