Use ck hashset to speed up our symbol table

This commit is contained in:
Justin Ethier 2015-12-11 22:27:21 -05:00
parent 6956396fea
commit 84d74409cb
3 changed files with 88 additions and 18 deletions

View file

@ -286,7 +286,7 @@
(comp-prog-cmd (comp-prog-cmd
(string-append "gcc " src-file " -g -c -o " exec-file ".o")) (string-append "gcc " src-file " -g -c -o " exec-file ".o"))
(comp-objs-cmd (comp-objs-cmd
(string-append "gcc " exec-file ".o " objs-str " -pthread -lcyclone -lm -g -o " exec-file))) (string-append "gcc " exec-file ".o " objs-str " -pthread -lcyclone -lck -lm -g -o " exec-file)))
;(write `(DEBUG all imports ,lib-deps objs ,objs-str)) ;(write `(DEBUG all imports ,lib-deps objs ,objs-str))
;(write `(DEBUG ,(lib:get-all-import-deps (cdar in-prog)))) ;(write `(DEBUG ,(lib:get-all-import-deps (cdar in-prog))))
(cond (cond

View file

@ -6,8 +6,10 @@
* This file contains the C runtime used by compiled programs. * This file contains the C runtime used by compiled programs.
*/ */
#include <ck_hs.h>
#include "cyclone/types.h" #include "cyclone/types.h"
#include "cyclone/runtime.h" #include "cyclone/runtime.h"
#include "cyclone/ck_ht_hash.h"
#include <signal.h> // TODO: only used for debugging! #include <signal.h> // TODO: only used for debugging!
//int JAE_DEBUG = 0; //int JAE_DEBUG = 0;
@ -97,10 +99,74 @@ char **_cyc_argv = NULL;
static symbol_type __EOF = {{0}, eof_tag, "", nil}; // symbol_type in lieu of custom type static symbol_type __EOF = {{0}, eof_tag, "", nil}; // symbol_type in lieu of custom type
const object Cyc_EOF = &__EOF; const object Cyc_EOF = &__EOF;
static ck_hs_t symbol_table;
static int symbol_table_size = 65536;
// Functions to support concurrency kit hashset
// These are specifically for a table of symbols
static void *hs_malloc(size_t r)
{
return malloc(r);
}
static void hs_free(void *p, size_t b, bool r)
{
// (void)b;
// (void)r;
free(p);
// return;
}
static struct ck_malloc my_allocator = {
.malloc = hs_malloc,
.free = hs_free
};
static unsigned long hs_hash(const void *object, unsigned long seed)
{
const symbol_type *c = object;
unsigned long h;
h = (unsigned long)MurmurHash64A(c->pname, strlen(c->pname), seed);
return h;
}
static bool hs_compare(const void *previous, const void *compare)
{
return strcmp(symbol_pname(previous), symbol_pname(compare)) == 0;
}
static void *set_get(ck_hs_t *hs, const void *value)
{
unsigned long h;
void *v;
h = CK_HS_HASH(hs, hs_hash, value);
v = ck_hs_get(hs, h, value);
return v;
}
static bool set_insert(ck_hs_t *hs, const void *value)
{
unsigned long h;
h = CK_HS_HASH(hs, hs_hash, value);
return ck_hs_put(hs, h, value);
}
// End supporting functions
void gc_init_heap(long heap_size) void gc_init_heap(long heap_size)
{ {
Cyc_heap = gc_heap_create(heap_size, 0, 0); Cyc_heap = gc_heap_create(heap_size, 0, 0);
if (!ck_hs_init(&symbol_table,
CK_HS_MODE_OBJECT | CK_HS_MODE_SPMC,
hs_hash, hs_compare,
&my_allocator,
symbol_table_size,
43423)){
fprintf(stderr, "Unable to initialize symbol table\n");
exit(1);
}
} }
gc_heap *gc_get_heap() gc_heap *gc_get_heap()
@ -166,8 +232,6 @@ void Cyc_st_print(FILE *out) {
For now, GC of symbols is missing. long-term it probably would be desirable For now, GC of symbols is missing. long-term it probably would be desirable
*/ */
list symbol_table = nil;
char *_strdup (const char *s) { char *_strdup (const char *s) {
char *d = malloc (strlen (s) + 1); char *d = malloc (strlen (s) + 1);
if (d) { strcpy (d,s); } if (d) { strcpy (d,s); }
@ -175,16 +239,23 @@ char *_strdup (const char *s) {
} }
object find_symbol_by_name(const char *name) { object find_symbol_by_name(const char *name) {
list l = symbol_table; symbol_type tmp = {{0}, symbol_tag, name, nil};
for (; !nullp(l); l = cdr(l)) { object result = set_get(&symbol_table, &tmp);
const char *str = symbol_pname(car(l)); //if (result) {
if (strcmp(str, name) == 0) return car(l); // printf("found symbol %s\n", symbol_pname(result));
} //}
return nil; return result;
} }
object add_symbol(symbol_type *psym) { object add_symbol(symbol_type *psym) {
symbol_table = mcons(psym, symbol_table); //printf("Adding symbol %s, table size = %ld\n", symbol_pname(psym), ck_hs_count(&symbol_table));
// TODO: lock table here, only allow one writer at a time
// TODO: grow table if it is not big enough
if (ck_hs_count(&symbol_table) == symbol_table_size) {
fprintf(stderr, "Ran out of symbol table entries\n");
exit(1);
}
set_insert(&symbol_table, psym);
return psym; return psym;
} }
@ -203,6 +274,7 @@ object find_or_add_symbol(const char *name){
return add_symbol_by_name(name); return add_symbol_by_name(name);
} }
} }
/* END symbol table */ /* END symbol table */
/* Global table */ /* Global table */

14
test.c
View file

@ -13,8 +13,7 @@ static void *hs_malloc(size_t r)
return malloc(r); return malloc(r);
} }
static void static void hs_free(void *p, size_t b, bool r)
hs_free(void *p, size_t b, bool r)
{ {
(void)b; (void)b;
(void)r; (void)r;
@ -27,8 +26,7 @@ static struct ck_malloc my_allocator = {
.free = hs_free .free = hs_free
}; };
static unsigned long static unsigned long hs_hash(const void *object, unsigned long seed)
hs_hash(const void *object, unsigned long seed)
{ {
// const char *c = object; // const char *c = object;
// unsigned long h; // unsigned long h;
@ -120,7 +118,7 @@ void main()
CK_HS_MODE_OBJECT | CK_HS_MODE_SPMC, CK_HS_MODE_OBJECT | CK_HS_MODE_SPMC,
hs_hash, hs_compare, hs_hash, hs_compare,
&my_allocator, &my_allocator,
2, 43423)){ 1024, 43423)){
fprintf(stderr, "Unable to initialize symbol table\n"); fprintf(stderr, "Unable to initialize symbol table\n");
exit(1); exit(1);
} }
@ -138,19 +136,19 @@ void main()
// printf("has \"b\" = %p\n", set_get(&hs_symbol_table, &b)); // printf("has \"b\" = %p\n", set_get(&hs_symbol_table, &b));
// printf("has \"c\" = %p\n", set_get(&hs_symbol_table, &c)); // printf("has \"c\" = %p\n", set_get(&hs_symbol_table, &c));
object asym = find_or_add_symbol("a"); object asym = find_or_add_symbol("producer");
printf("%p\n", asym); printf("%p\n", asym);
object bsym = find_or_add_symbol("b"); object bsym = find_or_add_symbol("b");
printf("hs length = %ld\n", ck_hs_count(&hs_symbol_table)); printf("hs length = %ld\n", ck_hs_count(&hs_symbol_table));
object csym = find_or_add_symbol("c"); object csym = find_or_add_symbol("lambda");
printf("hs length = %ld\n", ck_hs_count(&hs_symbol_table)); printf("hs length = %ld\n", ck_hs_count(&hs_symbol_table));
object dsym = find_or_add_symbol("d"); object dsym = find_or_add_symbol("d");
printf("hs length = %ld\n", ck_hs_count(&hs_symbol_table)); printf("hs length = %ld\n", ck_hs_count(&hs_symbol_table));
object aasym = find_or_add_symbol("a"); object aasym = find_or_add_symbol("producer");
printf("%p\n", aasym); printf("%p\n", aasym);
printf("hs length = %ld\n", ck_hs_count(&hs_symbol_table)); printf("hs length = %ld\n", ck_hs_count(&hs_symbol_table));
return; return;