C: day 24 final version + RESULTS.txt cleanup

This commit is contained in:
2022-10-19 18:14:02 +02:00
parent 94f0d95544
commit abcc4af572
3 changed files with 45 additions and 86 deletions

View File

@@ -506,13 +506,21 @@ ex2.bash: res=38162588308
+++++++++++++++++ ex1 +++++++++++++++++ ex1
ex1.bash: res=450 ex1.bash: res=450
time: 0:00.17 real, 0.17 user, 0.00 sys time: 0:00.17 real, 0.16 user, 0.00 sys
context-switch: 5+1, page-faults: 0+177 context-switch: 1+1, page-faults: 0+177
aoc-c : res=450
time: 0:00.00 real, 0.00 user, 0.00 sys
context-switch: 0+1, page-faults: 0+100
+++++++++++++++++ ex2 +++++++++++++++++ ex2
ex2.bash: res=4059 ex2.bash: res=4059
time: 0:22.35 real, 22.22 user, 0.07 sys time: 0:22.35 real, 22.22 user, 0.07 sys
context-switch: 1471+1, page-faults: 0+858 context-switch: 1102+1, page-faults: 0+858
aoc-c : res=4059
time: 0:00.04 real, 0.04 user, 0.00 sys
context-switch: 16+1, page-faults: 0+215
========================================= =========================================
================= day25 ================= ================= day25 =================

View File

@@ -30,7 +30,7 @@ CFLAGS += -std=gnu11
CFLAGS += -O2 CFLAGS += -O2
CFLAGS += -g CFLAGS += -g
# for gprof # for gprof
#CFLAGS += -pg # CFLAGS += -pg
CFLAGS += -Wall CFLAGS += -Wall
CFLAGS += -Wextra CFLAGS += -Wextra
CFLAGS += -march=native CFLAGS += -march=native
@@ -69,9 +69,11 @@ cpp: aoc-c.i
assembly: aoc-c.s assembly: aoc-c.s
ex1: aoc-c ex1: aoc-c
@$(TIME) ex1.bash -p 1 < $(INPUT)
@$(TIME) aoc-c -p 1 < $(INPUT) @$(TIME) aoc-c -p 1 < $(INPUT)
ex2: aoc-c ex2: aoc-c
@$(TIME) ex2.bash -p 2 < $(INPUT)
@$(TIME) aoc-c -p 2 < $(INPUT) @$(TIME) aoc-c -p 2 < $(INPUT)
ccls: $(CCLSFILE) ccls: $(CCLSFILE)

View File

@@ -16,11 +16,9 @@
* a new list after each process. * a new list after each process.
* So we will rely on a hashtable, which will allow to quickly find a * So we will rely on a hashtable, which will allow to quickly find a
* given point. * given point.
* We use here two hash-tables: One for the current situation(cur), one * We use here two hash-tables: One to keep the current black tiles, and
* for the next step (next); between steps, we clean cur and memcopy next * one for the neighbours count.
* to cur. It would be much better to swap hashtable pointers, but I wanted * My first try with the Linux kernel hashtables implementation.
* to use the hashtable.h API, where HASH_BITS() and HASH_SIZE() have to be
* macros (calculated during compilation; pointers not allowed here).
*/ */
typedef union coord { typedef union coord {
u64 val; u64 val;
@@ -33,24 +31,22 @@ typedef struct point {
coord_t pos; coord_t pos;
int count; int count;
struct hlist_node coll; /* entry in hash table */ struct hlist_node coll; /* entry in hash table */
struct list_head all;
} point_t; } point_t;
#define HBITS 9 /* in bits: 12 bits = 4096 */ #define HBITS 11 /* in bits: 12 bits = 4096 */
//#define HSIZE (1 << HBITS)
DEFINE_HASHTABLE(hasht_cur, HBITS); DEFINE_HASHTABLE(hasht_black, HBITS); /* current black tiles */
DEFINE_HASHTABLE(hasht_count, HBITS); DEFINE_HASHTABLE(hasht_count, HBITS); /* count of neighbours */
pool_t *pt_pool; pool_t *pt_pool;
static __always_inline u32 hash(coord_t p) static __always_inline u32 hash(coord_t p)
{ {
return hash_64(p.val, HASH_BITS(hasht_cur)); return hash_64(p.val, HASH_BITS(hasht_black));
} }
/** /**
* find_point - find point in hashtable * find_point - find entry in an hashtable bucket
*/ */
static point_t *find_point(struct hlist_head *head, coord_t p) static point_t *find_point(struct hlist_head *head, coord_t p)
{ {
@@ -82,33 +78,29 @@ static point_t *add_point(coord_t pos)
} }
/** /**
* flip_point - add point in hasht_cur hashtable, remove if it exists (init) * init_point - add point in hasht_black hashtable, remove if it exists (init)
*/ */
static point_t *flip_point(coord_t pos) static point_t *init_point(coord_t pos)
{ {
point_t *new; point_t *new;
u32 h; u32 h;
log_f(3, "val=%lu x=%d y=%d ", pos.val, pos.x, pos.y);
h = hash(pos); h = hash(pos);
log(3, "hash=%d ", h); if ((new = find_point(&hasht_black[h], pos))) {
if ((new = find_point(&hasht_cur[h], pos))) {
log(3, "removing tile\n");
hlist_del(&new->coll); hlist_del(&new->coll);
pool_add(pt_pool, new); pool_add(pt_pool, new);
new = NULL; new = NULL;
} else { } else {
log(3, "adding tile\n");
new = pool_get(pt_pool); new = pool_get(pt_pool);
new->pos.val = pos.val; new->pos.val = pos.val;
new->count = 0; new->count = 0;
hlist_add_head(&new->coll, &hasht_cur[h]); hlist_add_head(&new->coll, &hasht_black[h]);
} }
return new; return new;
} }
/** /**
* count_black - count elements in hasht_cur * count_black - count elements in hasht_black
*/ */
static int count_black() static int count_black()
{ {
@@ -116,68 +108,33 @@ static int count_black()
int res = 0; int res = 0;
ulong bucket; ulong bucket;
hash_for_each(hasht_cur, bucket, cur, coll) hash_for_each(hasht_black, bucket, cur, coll)
res++; res++;
return res; return res;
} }
/**
* reset_hasht_count - remove all points from hasht_count hashtable.
*/
static void reset_hasht_count()
{
point_t *cur;
struct hlist_node *tmp;
u32 bucket;
int count = 0;
hash_for_each_safe(hasht_count, bucket, tmp, cur, coll) {
hlist_del(&cur->coll);
pool_add(pt_pool, cur);
count++;
}
printf("removed %d counts\n", count);
}
/**
* move_next_cur - move hasht_next to hasht_cur
*/
/*
static void move_next_cur()
{
release_hasht_cur();
memcpy(hasht_cur, hasht_next, sizeof(hasht_next));
}
*/
static const coord_t neighbours [] = { static const coord_t neighbours [] = {
{ .x = 2, .y = 0 }, { .x = -2, .y = 0 }, /* east and west */ { .x = 2, .y = 0 }, { .x = -2, .y = 0 }, /* east and west */
{ .x = 1, .y = -1}, { .x = 1, .y = 1 }, /* SE and NE */ { .x = 1, .y = -1 }, { .x = 1, .y = 1 }, /* SE and NE */
{ .x = -1, .y = -1}, { .x = -1, .y = 1 } /* SW and NW */ { .x = -1, .y = -1 }, { .x = -1, .y = 1 } /* SW and NW */
}; };
/** /**
* count_neighbours - count hasht_cur neighbours, result in hasht_next * count_neighbours - count hasht_black neighbours, result in hasht_next
*/ */
static void count_neighbours() static void count_neighbours()
{ {
point_t *cur; point_t *cur;
u32 bucket; u32 bucket;
hash_for_each(hasht_cur, bucket, cur, coll) { hash_for_each(hasht_black, bucket, cur, coll) {
for (ulong i = 0; i < ARRAY_SIZE(neighbours); ++i) { for (int i = 0; i < (int) ARRAY_SIZE(neighbours); ++i) {
coord_t neigh = cur->pos; coord_t neigh = cur->pos;
neigh.x += neighbours[i].x; neigh.x += neighbours[i].x;
neigh.y += neighbours[i].y; neigh.y += neighbours[i].y;
add_point(neigh); add_point(neigh);
} }
} }
hash_for_each(hasht_count, bucket, cur, coll) {
log(3, "(%d,%d)=%d ", cur->pos.x, cur->pos.y, cur->count);
u32 h = hash(cur->pos);
point_t *tmp = find_point(&hasht_count[h], cur->pos);
if (tmp != cur)
log(3, "err:%p!=%p ", cur, tmp);
}
} }
/** /**
@@ -189,33 +146,30 @@ static void adjust_neighbours()
u32 bucket; u32 bucket;
struct hlist_node *tmp; struct hlist_node *tmp;
/* 1) check hasht_cur tiles (currently black) /* 1) check hasht_black tiles (currently black)
*/ */
hash_for_each_safe(hasht_cur, bucket, tmp, pt_cur, coll) { hash_for_each_safe(hasht_black, bucket, tmp, pt_cur, coll) {
int h = hash(pt_cur->pos); int h = hash(pt_cur->pos);
point_t *pt_count = find_point(&hasht_count[h], pt_cur->pos); point_t *pt_count = find_point(&hasht_count[h], pt_cur->pos);
if (!pt_count || pt_count->count > 2) { if (!pt_count || pt_count->count > 2) {
log(3, "P1 removing %d (%d,%d)\n", pt_count? pt_count->count: 0, hash_del(&pt_cur->coll);
pt_cur->pos.x, pt_cur->pos.y);
hlist_del(&pt_cur->coll);
pool_add(pt_pool, pt_cur); pool_add(pt_pool, pt_cur);
} else {
log(3, "P1 keeping %d (%d,%d)\n", pt_count? pt_count->count: 0,
pt_cur->pos.x, pt_cur->pos.y);
} }
/* we do not want to re-consider this point in next loop /* we do not want to re-consider this point in next loop
*/ */
if (pt_count) { if (pt_count) {
hlist_del(&pt_count->coll); hash_del(&pt_count->coll);
pool_add(pt_pool, pt_count); pool_add(pt_pool, pt_count);
} }
} }
/* 2) check remaining points in hasht_next (currently white) /* 2) check remaining points in hasht_next (currently white)
*/ */
hash_for_each_safe(hasht_count, bucket, tmp, pt_count, coll) { hash_for_each_safe(hasht_count, bucket, tmp, pt_count, coll) {
if (pt_count->count == 2) {
hash_del(&pt_count->coll); hash_del(&pt_count->coll);
hash_add(hasht_cur, &pt_count->coll, hash(pt_count->pos)); if (pt_count->count == 2) {
hash_add(hasht_black, &pt_count->coll, hash(pt_count->pos));
} else {
pool_add(pt_pool, pt_count);
} }
} }
} }
@@ -229,7 +183,6 @@ static void parse()
while ((len = getline(&buf, &alloc, stdin)) > 0) { while ((len = getline(&buf, &alloc, stdin)) > 0) {
buf[len - 1] = 0; buf[len - 1] = 0;
coord_t p = { .val = 0 }; coord_t p = { .val = 0 };
puts(buf);
char *c = buf; char *c = buf;
while (*c) { while (*c) {
switch (*c) { switch (*c) {
@@ -243,10 +196,10 @@ static void parse()
else if (*c == 'w') else if (*c == 'w')
--p.x; --p.x;
c++; c++;
//printf("pos=%ld x=%d y=%d\n", c - buf, p.x, p.y);
} }
flip_point(p); init_point(p);
} }
free(buf);
} }
static int usage(char *prg) static int usage(char *prg)
@@ -276,18 +229,14 @@ int main(ac, av)
} }
pt_pool = pool_create("pool_points", 512, sizeof(point_t)); pt_pool = pool_create("pool_points", 512, sizeof(point_t));
parse(); parse();
printf("initial count = %d\n", count_black());
if (part == 2) { if (part == 2) {
for (int i = 0; i < 100; ++i) { for (int i = 0; i < 100; ++i) {
reset_hasht_count();
count_neighbours(); count_neighbours();
adjust_neighbours(); adjust_neighbours();
printf("count after loop %d = %d\n", i + 1, count_black());
} }
} }
res = count_black(); res = count_black();
printf("size=%lu\n", sizeof(hasht_count));
printf("%s : res=%d\n", *av, res); printf("%s : res=%d\n", *av, res);
pool_stats(pt_pool); pool_destroy(pt_pool);
exit (0); exit (0);
} }