From 61c3a9aa7a636ada2cedd5b6025d5c7ccc598c85 Mon Sep 17 00:00:00 2001 From: Gediminas Jakutis Date: Tue, 10 Mar 2020 10:15:53 +0200 Subject: bolt on data generation, kind of. Signed-off-by: Gediminas Jakutis --- src/cache.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cache.h | 16 ++++++++++++++++ src/datagen.c | 34 ++++++++++++++++++++++++++++------ src/datagen.h | 8 +++++++- src/defs.h | 32 +++++++++++++++++++++++++++----- src/io.c | 28 +++++++++------------------- src/io.h | 6 ++++-- src/main.c | 25 +++++++++++++++---------- src/meson.build | 8 +++++--- 9 files changed, 167 insertions(+), 46 deletions(-) create mode 100644 src/cache.c create mode 100644 src/cache.h (limited to 'src') diff --git a/src/cache.c b/src/cache.c new file mode 100644 index 0000000..c88cc78 --- /dev/null +++ b/src/cache.c @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: LGPL-2.1-only */ + +/* Copyright (C) 2020 Gediminas Jakutis */ + +#include +#include +#include "defs.h" + +int cache_create(struct stream * const restrict in, const struct settings * const restrict s) +{ + int ret; + void *cache; + + try(!(cache = calloc(in->n, s->stride)), err, ENOMEM); + + in->cache = cache; +err: + return ret; +} + +int cache_populate(struct stream * const restrict in) +{ + int ret = 0; + ssize_t i; + + for (i = 0; i < in->n; ++i) { + try_s((ret = in->get_element(in, i, in->cache + i)), err); + } + +err: + return ret; +} + +int cache_flush(struct stream * const in) +{ + int ret; + ssize_t i; + + for (i = 0; i < in->n; ++i) { + try_s((ret = in->put_element(in, i, in->cache + i)), err); + } + +err: + return ret; +} + +int cache_destroy(struct stream * const in) +{ + int ret; + + try(!in->cache, err, EINVAL); + free(in->cache); + in->cache = NULL; +err: + return ret; +} diff --git a/src/cache.h b/src/cache.h new file mode 100644 index 0000000..0607112 --- /dev/null +++ b/src/cache.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: LGPL-2.1-only */ + +/* Copyright (C) 2020 Gediminas Jakutis */ + +#ifndef ALGOS_CACHE_H_INCLUDED +#define ALGOS_CACHE_H_INCLUDED + +#include +#include "defs.h" + +int cache_create(struct stream * const restrict in, const struct settings * const restrict s); +int cache_populate(struct stream * const restrict in); +int cache_flush(struct stream * const in); +int cache_destroy(struct stream * const in); + +#endif /* ALGOS_CACHE_H_INCLUDED */ diff --git a/src/datagen.c b/src/datagen.c index 9efe3b3..d4c8bab 100644 --- a/src/datagen.c +++ b/src/datagen.c @@ -1,19 +1,20 @@ +/* SPDX-License-Identifier: LGPL-2.1-only */ + +/* Copyright (C) 2020 Gediminas Jakutis */ + #include #include #include +#include +#include #include "datagen.h" #include "defs.h" -int gen_get(struct stream *in, size_t idx, struct entry_l *data, int tag) +int gen_get_array(struct stream * const restrict in, ssize_t idx, struct entry_l * const data) { int ret = 0; (void) idx; - if (tag) { - data->prev = 0; - data->next = 0; - } - in->prev_idx = -1; ret = read(in->fd, &data->val, sizeof(data->val)); @@ -23,3 +24,24 @@ int gen_get(struct stream *in, size_t idx, struct entry_l *data, int tag) return ret; } + +int gen_get_list(struct stream * const restrict in, ssize_t idx, struct entry_l * const data) +{ + int ret = 0; + + data->prev = idx > 0 ? idx - 1 : labs(idx) - 1; + data->next = idx + 1; + + if (!idx) { + data->val = 0; /* header lmao */ + } else { + ret = gen_get_array(in, idx, data); + } + + return ret; +} + +int gen_put(struct stream * const restrict in, ssize_t idx, const struct entry_l * const data) +{ + return ENOSYS; +} diff --git a/src/datagen.h b/src/datagen.h index 7e753ab..63b3461 100644 --- a/src/datagen.h +++ b/src/datagen.h @@ -1,8 +1,14 @@ +/* SPDX-License-Identifier: LGPL-2.1-only */ + +/* Copyright (C) 2020 Gediminas Jakutis */ + #ifndef ALGOS_DATAGEN_H_INCLUDED #define ALGOS_DATAGEN_H_INCLUDED #include "defs.h" -int gen_get(struct stream *in, size_t idx, struct entry_l *data, int tag); +int gen_get_array(struct stream * const restrict in, ssize_t idx, struct entry_l * const data); +int gen_get_list(struct stream * const restrict in, ssize_t idx, struct entry_l * const data); +int gen_put(struct stream * const restrict in, ssize_t idx, const struct entry_l * const data); #endif /* ALGOS_DATAGEN_H_INCLUDED */ diff --git a/src/defs.h b/src/defs.h index 1ad2d72..3b8f1c1 100644 --- a/src/defs.h +++ b/src/defs.h @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: LGPL-2.1-only */ + +/* Copyright (C) 2020 Gediminas Jakutis */ + #ifndef ALGOS_DEFS_H_INCLUDED #define ALGOS_DEFS_H_INCLUDED @@ -16,6 +20,9 @@ goto l;\ }} while (0); +#define get(in, idx, data) (in->cached ? in->get_element_cache(in, idx, data) | in->get_element(in, idx, data)) +#define put(in, idx, data) (in->cached ? in->put_element_cache(in, idx, data) | in->put_element(in, idx, data)) + /* for array implementation */ struct entry { uint64_t val; @@ -24,8 +31,8 @@ struct entry { /* for linked list implementation */ struct entry_l { struct entry; - uint32_t next; /* """pointer""" to the next element. */ - uint32_t prev; /* """pointer""" to the previous element. */ + int32_t next; /* """pointer""" to the next element. */ + int32_t prev; /* """pointer""" to the previous element. */ }; enum opmode { @@ -34,14 +41,28 @@ enum opmode { mode_generate }; +enum accessmode { + cached, + direct +}; + +enum dataformat { + array, + list +}; + struct stream { size_t n; ssize_t prev_idx; int fd; int out; + int cached; char *name; - int (*get)(struct stream *, size_t, struct entry_l *, int); - int (*put)(struct stream *, size_t, struct entry_l *, int); + struct entry_l *cache; + int (*get_element)(struct stream * const restrict, size_t, struct entry_l *); + int (*put_element)(struct stream * const restrict, size_t, struct entry_l *); + int (*get_element_cache)(struct stream * const restrict, size_t, struct entry_l *); + int (*put_element_cache)(struct stream * const restrict, size_t, struct entry_l *); }; struct settings { @@ -50,8 +71,9 @@ struct settings { size_t stride; char *filein; char *fileout; - unsigned int flags; enum opmode opmode; + enum dataformat format; + enum accessmode access; }; #endif /* ALGOS_DEFS_H_INCLUDED */ diff --git a/src/io.c b/src/io.c index 04f53b1..b18cc00 100644 --- a/src/io.c +++ b/src/io.c @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: LGPL-2.1-only */ + +/* Copyright (C) 2020 Gediminas Jakutis */ + #include #include #include @@ -11,6 +15,7 @@ #include "io.h" #include "defs.h" #include "datagen.h" +#include "cache.h" static int stream_open_in(struct stream * const in, const struct settings * const s); static int stream_open_out(struct stream * const in, const struct settings * const s); @@ -74,25 +79,6 @@ early_err: return ret; } -int stream_get(struct stream *in, size_t idx, struct entry_l *data, int tag) -{ - int ret = 0; - - ret = in->get(in, idx, data, tag); - - return ret; -} - -int stream_put(struct stream *in, size_t idx, struct entry_l *data, int tag) -{ - int ret = 0; - - ret = in->put(in, idx, data, tag); - - return ret; -} - - static int stream_open_out(struct stream * const in, const struct settings * const s) { struct stat st; @@ -133,6 +119,10 @@ static int stream_open_in(struct stream * const in, const struct settings * cons in->n = st.st_size / s->stride; in->fd = open(in->name, O_RDONLY | O_NOATIME); try(in->fd < 0, err, errno); /* TODO: err msg */ + if (in->cached) { + cache_create(in, s); + cache_populate(in); + } err: return ret; diff --git a/src/io.h b/src/io.h index d76f2b3..792ebd2 100644 --- a/src/io.h +++ b/src/io.h @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: LGPL-2.1-only */ + +/* Copyright (C) 2020 Gediminas Jakutis */ + #ifndef ALGOS_IO_H_INCLUDED #define ALGOS_IO_H_INCLUDED @@ -5,7 +9,5 @@ int stream_open(struct stream * const in, const struct settings * const s); int stream_close(struct stream * const in); -int stream_get(struct stream *in, size_t idx, struct entry_l *data, int tag); -int stream_put(struct stream *in, size_t idx, struct entry_l *data, int tag); #endif /* ALGOS_IO_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 0d9109f..fabc612 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: LGPL-2.1-only */ + +/* Copyright (C) 2020 Gediminas Jakutis */ + #include #include #include @@ -6,9 +10,6 @@ #include "io.h" #include "defs.h" -static const unsigned int FLAG_DATA_FORMAT = (1 << 0); -static const unsigned int FLAG_DATA_ACCESS = (1 << 1); - static char randfile[] = "/dev/urandom"; static struct settings settings = {0}; @@ -62,13 +63,13 @@ static int parseargs(int argc, char **argv, struct settings * settings) } else if (!(strcmp(argv[i], "--generate"))) { s.opmode = mode_generate; } else if (!(strcmp(argv[i], "--array"))) { - s.opmode &= ~FLAG_DATA_FORMAT; + s.format = array; } else if (!(strcmp(argv[i], "--list"))) { - s.opmode |= FLAG_DATA_FORMAT; + s.format = list; } else if (!(strcmp(argv[i], "--cache"))) { - s.opmode &= ~FLAG_DATA_ACCESS; + s.access = cached; } else if (!(strcmp(argv[i], "--no-cache"))) { - s.opmode |= FLAG_DATA_ACCESS; + s.access = direct; } else if (!(strncmp(argv[i], "--position=", 11))) { if (strlen(argv[i]) > 11) { s.ss = strtoul(argv[i] + 11, NULL, 10); @@ -104,13 +105,17 @@ static int parseargs(int argc, char **argv, struct settings * settings) if (s.opmode == mode_generate) { - /* we always generate in-memory for speed */ - s.opmode &= ~FLAG_DATA_ACCESS; + /* we always generate in-memory for PERFORMANCE */ + s.access = cached; + if (s.format == list) { + /* we need to generate the empty header, too */ + ++s.to; + } } else if (s.opmode == mode_fetch) { s.to = s.ss + s.to; } - s.stride = s.opmode & FLAG_DATA_FORMAT ? sizeof(struct entry_l) : sizeof(struct entry); + s.stride = s.format == list ? sizeof(struct entry_l) : sizeof(struct entry); *settings = s; diff --git a/src/meson.build b/src/meson.build index f353e54..f94cce4 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,13 +1,15 @@ source_files = [ - 'main.c', - 'io.c', + 'cache.c', 'datagen.c', + 'io.c', + 'main.c', ] header_files = [ - 'io.h', + 'cache.h', 'defs.h', 'datagen.h', + 'io.h', ] sources = files(source_files) -- cgit v1.2.3