1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-13 17:20:21 +02:00

Clean up gcbench naming, to be consistent

This commit is contained in:
Andy Wingo 2022-03-18 09:42:20 +01:00
parent 7dda5b992d
commit 887bdd5441

225
gcbench.c
View file

@ -46,24 +46,24 @@
#include "gcbench-types.h" #include "gcbench-types.h"
#include "gc.h" #include "gc.h"
static const int kStretchTreeDepth = 18; // about 16Mb static const int stretch_tree_depth = 18; // about 16Mb
static const int kLongLivedTreeDepth = 16; // about 4Mb static const int long_lived_tree_depth = 16; // about 4Mb
static const int kArraySize = 500000; // about 4Mb static const int array_size = 500000; // about 4Mb
static const int kMinTreeDepth = 4; static const int min_tree_depth = 4;
static const int kMaxTreeDepth = 16; static const int max_tree_depth = 16;
typedef struct Node { struct Node {
GC_HEADER; GC_HEADER;
struct Node * left; struct Node * left;
struct Node * right; struct Node * right;
int i, j; int i, j;
} Node; };
typedef struct DoubleArray { struct DoubleArray {
GC_HEADER; GC_HEADER;
size_t length; size_t length;
double values[0]; double values[0];
} DoubleArray; };
static inline size_t node_size(Node *obj) { static inline size_t node_size(Node *obj) {
return sizeof(Node); return sizeof(Node);
@ -92,7 +92,7 @@ static Node* allocate_node(struct context *cx) {
return allocate(cx, ALLOC_KIND_NODE, sizeof (Node)); return allocate(cx, ALLOC_KIND_NODE, sizeof (Node));
} }
static struct DoubleArray* allocate_double_array(struct context *cx, static DoubleArray* allocate_double_array(struct context *cx,
size_t size) { size_t size) {
// May be uninitialized. // May be uninitialized.
DoubleArray *ret = DoubleArray *ret =
@ -102,73 +102,71 @@ static struct DoubleArray* allocate_double_array(struct context *cx,
return ret; return ret;
} }
/* Get the current time in milliseconds */ static unsigned long current_time(void)
static unsigned currentTime(void)
{ {
struct timeval t; struct timeval t = { 0 };
struct timezone tz; gettimeofday(&t, NULL);
return t.tv_sec * 1000 * 1000 + t.tv_usec;
if (gettimeofday( &t, &tz ) == -1)
return 0;
return (t.tv_sec * 1000 + t.tv_usec / 1000);
} }
void init_Node(Node *me, Node *l, Node *r) { static double elapsed_millis(unsigned long start) {
init_field((void**)&me->left, l); return (current_time() - start) * 1e-3;
init_field((void**)&me->right, r);
} }
// Nodes used by a tree of a given size // Nodes used by a tree of a given size
static int TreeSize(int i) { static int tree_size(int i) {
return ((1 << (i + 1)) - 1); return ((1 << (i + 1)) - 1);
} }
// Number of iterations to use for a given tree depth // Number of iterations to use for a given tree depth
static int NumIters(int i) { static int compute_num_iters(int i) {
return 2 * TreeSize(kStretchTreeDepth) / TreeSize(i); return 2 * tree_size(stretch_tree_depth) / tree_size(i);
} }
// Build tree top down, assigning to older objects. // Build tree top down, assigning to older objects.
static void Populate(struct context *cx, int iDepth, Node *node) { static void populate(struct context *cx, int depth, Node *node) {
if (iDepth<=0) { if (depth <= 0)
return; return;
} else {
iDepth--; NodeHandle self = { node };
PUSH_HANDLE(cx, self);
NodeHandle self = { node }; NodeHandle l = { allocate_node(cx) };
PUSH_HANDLE(cx, self); PUSH_HANDLE(cx, l);
NodeHandle l = { allocate_node(cx) }; NodeHandle r = { allocate_node(cx) };
PUSH_HANDLE(cx, l); PUSH_HANDLE(cx, r);
NodeHandle r = { allocate_node(cx) };
PUSH_HANDLE(cx, r); set_field((void**)&HANDLE_REF(self)->left, HANDLE_REF(l));
set_field((void**)&HANDLE_REF(self)->left, HANDLE_REF(l)); set_field((void**)&HANDLE_REF(self)->right, HANDLE_REF(r));
set_field((void**)&HANDLE_REF(self)->right, HANDLE_REF(r));
Populate (cx, iDepth, HANDLE_REF(self)->left); populate(cx, depth-1, HANDLE_REF(self)->left);
Populate (cx, iDepth, HANDLE_REF(self)->right); populate(cx, depth-1, HANDLE_REF(self)->right);
POP_HANDLE(cx);
POP_HANDLE(cx); POP_HANDLE(cx);
POP_HANDLE(cx); POP_HANDLE(cx);
} POP_HANDLE(cx);
} }
// Build tree bottom-up // Build tree bottom-up
static Node* MakeTree(struct context *cx, int iDepth) { static Node* make_tree(struct context *cx, int depth) {
if (iDepth<=0) { if (depth <= 0)
return allocate_node(cx); return allocate_node(cx);
} else {
NodeHandle left = { MakeTree(cx, iDepth-1) }; NodeHandle left = { make_tree(cx, depth-1) };
PUSH_HANDLE(cx, left); PUSH_HANDLE(cx, left);
NodeHandle right = { MakeTree(cx, iDepth-1) }; NodeHandle right = { make_tree(cx, depth-1) };
PUSH_HANDLE(cx, right); PUSH_HANDLE(cx, right);
Node *result = allocate_node(cx);
init_Node(result, HANDLE_REF(left), HANDLE_REF(right)); Node *result = allocate_node(cx);
POP_HANDLE(cx); init_field((void**)&result->left, HANDLE_REF(left));
POP_HANDLE(cx); init_field((void**)&result->right, HANDLE_REF(right));
return result;
} POP_HANDLE(cx);
POP_HANDLE(cx);
return result;
} }
static void ValidateTree(Node *tree, int depth) { static void validate_tree(Node *tree, int depth) {
#ifndef NDEBUG #ifndef NDEBUG
ASSERT_EQ(tree->i, 0); ASSERT_EQ(tree->i, 0);
ASSERT_EQ(tree->j, 0); ASSERT_EQ(tree->j, 0);
@ -178,120 +176,115 @@ static void ValidateTree(Node *tree, int depth) {
} else { } else {
ASSERT(tree->left); ASSERT(tree->left);
ASSERT(tree->right); ASSERT(tree->right);
ValidateTree(tree->left, depth - 1); validate_tree(tree->left, depth - 1);
ValidateTree(tree->right, depth - 1); validate_tree(tree->right, depth - 1);
} }
#endif #endif
} }
static void TimeConstruction(struct context *cx, int depth) { static void time_construction(struct context *cx, int depth) {
int iNumIters = NumIters(depth); int num_iters = compute_num_iters(depth);
NodeHandle tempTree = { NULL }; NodeHandle temp_tree = { NULL };
PUSH_HANDLE(cx, tempTree); PUSH_HANDLE(cx, temp_tree);
printf("Creating %d trees of depth %d\n", iNumIters, depth); printf("Creating %d trees of depth %d\n", num_iters, depth);
{ {
long tStart = currentTime(); unsigned long start = current_time();
for (int i = 0; i < iNumIters; ++i) { for (int i = 0; i < num_iters; ++i) {
HANDLE_SET(tempTree, allocate_node(cx)); HANDLE_SET(temp_tree, allocate_node(cx));
Populate(cx, depth, HANDLE_REF(tempTree)); populate(cx, depth, HANDLE_REF(temp_tree));
ValidateTree(HANDLE_REF(tempTree), depth); validate_tree(HANDLE_REF(temp_tree), depth);
HANDLE_SET(tempTree, NULL); HANDLE_SET(temp_tree, NULL);
} }
long tFinish = currentTime(); printf("\tTop down construction took %.3f msec\n",
printf("\tTop down construction took %ld msec\n", elapsed_millis(start));
tFinish - tStart);
} }
{ {
long tStart = currentTime(); long start = current_time();
for (int i = 0; i < iNumIters; ++i) { for (int i = 0; i < num_iters; ++i) {
HANDLE_SET(tempTree, MakeTree(cx, depth)); HANDLE_SET(temp_tree, make_tree(cx, depth));
ValidateTree(HANDLE_REF(tempTree), depth); validate_tree(HANDLE_REF(temp_tree), depth);
HANDLE_SET(tempTree, NULL); HANDLE_SET(temp_tree, NULL);
} }
long tFinish = currentTime(); printf("\tBottom up construction took %.3f msec\n",
printf("\tBottom up construction took %ld msec\n", elapsed_millis(start));
tFinish - tStart);
} }
POP_HANDLE(cx); POP_HANDLE(cx);
} }
int main() { int main() {
size_t kHeapMaxLive = size_t heap_max_live =
2 * sizeof(struct Node) * TreeSize(kLongLivedTreeDepth) + 2 * sizeof(Node) * tree_size(long_lived_tree_depth) +
sizeof(double) * kArraySize; sizeof(double) * array_size;
double kHeapMultiplier = 3; double heap_multiplier = 3;
size_t kHeapSize = kHeapMaxLive * kHeapMultiplier; size_t heap_size = heap_max_live * heap_multiplier;
if (getenv("HEAP_SIZE")) if (getenv("HEAP_SIZE"))
kHeapSize = atol(getenv("HEAP_SIZE")); heap_size = atol(getenv("HEAP_SIZE"));
if (!kHeapSize) { if (!heap_size) {
fprintf(stderr, "Failed to parse HEAP_SIZE='%s'\n", getenv("HEAP_SIZE")); fprintf(stderr, "Failed to parse HEAP_SIZE='%s'\n", getenv("HEAP_SIZE"));
return 1; return 1;
} }
struct context *cx = initialize_gc(kHeapSize); struct context *cx = initialize_gc(heap_size);
if (!cx) { if (!cx) {
fprintf(stderr, "Failed to initialize GC with heap size %zu bytes\n", fprintf(stderr, "Failed to initialize GC with heap size %zu bytes\n",
kHeapSize); heap_size);
return 1; return 1;
} }
NodeHandle root = { NULL }; NodeHandle root = { NULL };
NodeHandle longLivedTree = { NULL }; NodeHandle long_lived_tree = { NULL };
NodeHandle tempTree = { NULL }; NodeHandle temp_tree = { NULL };
DoubleArrayHandle array = { NULL }; DoubleArrayHandle array = { NULL };
PUSH_HANDLE(cx, root); PUSH_HANDLE(cx, root);
PUSH_HANDLE(cx, longLivedTree); PUSH_HANDLE(cx, long_lived_tree);
PUSH_HANDLE(cx, tempTree); PUSH_HANDLE(cx, temp_tree);
PUSH_HANDLE(cx, array); PUSH_HANDLE(cx, array);
printf("Garbage Collector Test\n"); printf("Garbage Collector Test\n");
printf(" Live storage will peak at %zd bytes.\n\n", kHeapMaxLive); printf(" Live storage will peak at %zd bytes.\n\n", heap_max_live);
printf(" Stretching memory with a binary tree of depth %d\n", printf(" Stretching memory with a binary tree of depth %d\n",
kStretchTreeDepth); stretch_tree_depth);
print_start_gc_stats(cx); print_start_gc_stats(cx);
long tStart = currentTime(); unsigned long start = current_time();
// Stretch the memory space quickly // Stretch the memory space quickly
HANDLE_SET(tempTree, MakeTree(cx, kStretchTreeDepth)); HANDLE_SET(temp_tree, make_tree(cx, stretch_tree_depth));
ValidateTree(HANDLE_REF(tempTree), kStretchTreeDepth); validate_tree(HANDLE_REF(temp_tree), stretch_tree_depth);
HANDLE_SET(tempTree, NULL); HANDLE_SET(temp_tree, NULL);
// Create a long lived object // Create a long lived object
printf(" Creating a long-lived binary tree of depth %d\n", printf(" Creating a long-lived binary tree of depth %d\n",
kLongLivedTreeDepth); long_lived_tree_depth);
HANDLE_SET(longLivedTree, allocate_node(cx)); HANDLE_SET(long_lived_tree, allocate_node(cx));
Populate(cx, kLongLivedTreeDepth, HANDLE_REF(longLivedTree)); populate(cx, long_lived_tree_depth, HANDLE_REF(long_lived_tree));
// Create long-lived array, filling half of it // Create long-lived array, filling half of it
printf(" Creating a long-lived array of %d doubles\n", kArraySize); printf(" Creating a long-lived array of %d doubles\n", array_size);
HANDLE_SET(array, allocate_double_array(cx, kArraySize)); HANDLE_SET(array, allocate_double_array(cx, array_size));
for (int i = 0; i < kArraySize/2; ++i) { for (int i = 0; i < array_size/2; ++i) {
HANDLE_REF(array)->values[i] = 1.0/i; HANDLE_REF(array)->values[i] = 1.0/i;
} }
for (int d = kMinTreeDepth; d <= kMaxTreeDepth; d += 2) { for (int d = min_tree_depth; d <= max_tree_depth; d += 2) {
TimeConstruction(cx, d); time_construction(cx, d);
} }
ValidateTree(HANDLE_REF(longLivedTree), kLongLivedTreeDepth); validate_tree(HANDLE_REF(long_lived_tree), long_lived_tree_depth);
if (HANDLE_REF(longLivedTree) == 0 // Fake reference to LongLivedTree and array to keep them from being optimized
// away.
if (HANDLE_REF(long_lived_tree) == 0
|| HANDLE_REF(array)->values[1000] != 1.0/1000) || HANDLE_REF(array)->values[1000] != 1.0/1000)
fprintf(stderr, "Failed\n"); fprintf(stderr, "Failed\n");
// fake reference to LongLivedTree
// and array
// to keep them from being optimized away
long tFinish = currentTime(); printf("Completed in %.3f msec\n", elapsed_millis(start));
long tElapsed = tFinish - tStart;
printf("Completed in %ld msec\n", tElapsed);
print_end_gc_stats(cx); print_end_gc_stats(cx);
POP_HANDLE(cx); POP_HANDLE(cx);