advent2023

Advent of Code 2023 solutions
git clone git://bsandro.tech/advent2023
Log | Files | Refs | LICENSE

commit 54fd25077b19ed9ce6d4c5a42b54bf8ce0bc0ff7
parent 3f4956957b32cde2b5e303345cd94929252395ae
Author: bsandro <email@bsandro.tech>
Date:   Wed,  6 Dec 2023 21:52:30 +0200

day 05 p2 with lots of abusing native C11 and Ryzen power

Diffstat:
Mday05/Makefile | 4++--
Mday05/main.c | 5+++++
Mday05/puzzle.c | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
3 files changed, 99 insertions(+), 9 deletions(-)

diff --git a/day05/Makefile b/day05/Makefile @@ -2,8 +2,8 @@ NAME=$(shell basename ${PWD}) SRC=$(wildcard *.c) DEPS:=$(wildcard *.h) OBJ:=$(SRC:.c=.o) -CFLAGS=-O2 -std=c11 -Werror -Wall -Wextra -I. -I../common -LDFLAGS=-lc +CFLAGS=-O2 -std=c11 -pthread -Werror -Wall -Wextra -I. -I../common +LDFLAGS=-lc -pthread all: $(NAME) diff --git a/day05/main.c b/day05/main.c @@ -1,6 +1,9 @@ #include <stdio.h> #include <time.h> #include <string.h> +#include <threads.h> +#include <stdatomic.h> +#include <stdlib.h> void puzzle(const char *filename, long long *res1, long long *res2); //void puzzle_test(const char *filename, long long *res1, long long *res2); @@ -26,5 +29,7 @@ int main(int argc, char *argv[]) { double elapsed = clock() - time_start; printf("Elapsed: %f\n", elapsed / CLOCKS_PER_SEC); + thrd_exit(EXIT_SUCCESS); + return 0; } diff --git a/day05/puzzle.c b/day05/puzzle.c @@ -9,6 +9,8 @@ #include <assert.h> #include <stdbool.h> #include <inttypes.h> +#include <stdatomic.h> +#include <threads.h> #define STR_LEN 2048 @@ -86,6 +88,40 @@ void fill_range(Range *r, uint64_t dst_start, uint64_t src_start, uint64_t len) r->dst[1] = dst_start + len; } +typedef struct RunArgs { + Range *ranges; + uint64_t seed1; + uint64_t seed2; + mtx_t *mutex; + long long *result2; +} RunArgs; + +int run_calc(void *a) { + RunArgs *ra = (RunArgs *)a; + uint64_t seed1 = ra->seed1; + uint64_t seed2 = ra->seed2; + Range *ranges = ra->ranges; + uint64_t res2 = 0; + //printf("seed from %" PRIu64 " of count %" PRIu64 "\n", seed1, seed2); + + // brain damage + for (uint64_t i=seed1; i<seed1+seed2; ++i) { + uint64_t loc = calc_loc(ranges, i); + if (res2==0||loc<res2) res2 = loc; + } + //printf("res2: %" PRIu64 "\n", res2); + if (mtx_lock(ra->mutex)!=thrd_success) { + printf("mutex lock error\n"); + //thrd_exit(EXIT_FAILURE); + } + if (*ra->result2==-1||res2<(uint64_t)*ra->result2) *ra->result2 = res2; + if (mtx_unlock(ra->mutex)!=thrd_success) { + printf("mutex unlock error\n"); + //thrd_exit(EXIT_FAILURE); + } + return 0; +} + void puzzle(const char *filename, long long *result1, long long *result2) { FILE *infile = fopen(filename, "r"); if (infile == NULL) { @@ -96,8 +132,6 @@ void puzzle(const char *filename, long long *result1, long long *result2) { char buf[STR_LEN] = {0}; unsigned int line_num = 0; - *result2 = 0; - Number *seeds = NULL; Number *seeds_last = NULL; @@ -146,14 +180,65 @@ void puzzle(const char *filename, long long *result1, long long *result2) { } //print_ranges(ranges); - Number *s = seeds; - while (s!=NULL) { - uint64_t loc = calc_loc(ranges, s->value); + Number *s1 = seeds; + while (s1!=NULL) { + uint64_t loc = calc_loc(ranges, s1->value); if (*result1==-1||loc<(uint64_t)*result1) *result1 = loc; - //printf("seed %" PRIu64 " location: %" PRIu64 "\n", s->value, loc); - s = s->next; + //printf("seed %" PRIu64 " location: %" PRIu64 "\n", s1->value, loc); + s1 = s1->next; + } + + Number *s2 = seeds; + thrd_t threads[10] = {0}; + int thread_id = 0; + static mtx_t mutex; + if (mtx_init(&mutex, mtx_plain)!=thrd_success) { + printf("error initing mutex\n"); + thrd_exit(EXIT_FAILURE); + } + while (s2!=NULL) { + uint64_t seed1 = s2->value; + uint64_t seed2 = 0; + if (s2->next!=NULL) { + seed2 = s2->next->value; + s2 = s2->next->next; + } + //printf("seed from %" PRIu64 " of count %" PRIu64 "\n", seed1, seed2); + + // brain damage + /*for (uint64_t i=seed1; i<seed1+seed2; ++i) { + uint64_t loc = calc_loc(ranges, i); + if (*result2==-1||loc<(uint64_t)*result2) *result2 = loc; + }*/ + RunArgs *a = malloc(sizeof(RunArgs)); + a->ranges = ranges; + a->seed1 = seed1; + a->seed2 = seed2; + a->result2 = result2; + a->mutex = &mutex; + int t_res=thrd_create(&threads[thread_id], run_calc, (void *)a); + if (t_res!=thrd_success) { + printf("thrd_create %d error %d\n", thread_id, t_res); + } + ++thread_id; + } + + for (int i=0; i<thread_id; ++i) { + //printf("waiting for t %d\n", i); + int t_out = 0; + int t_res = thrd_join(threads[i], &t_out); + if (t_res!=thrd_success) { + printf("error joining thread %d: %d (out %d)\n", i, t_res, t_out); + //thrd_exit(EXIT_FAILURE); + } + //printf("end waiting for t %d\n", i); } // mutiny! ignoring feof/ferror. fclose(infile); + + //printf("res1: %lld\n", *result1); + //printf("res2: %lld\n", *result2); + + //thrd_exit(EXIT_SUCCESS); }