This commit is contained in:
Gregory Burd 2024-05-02 21:13:17 -04:00
parent 86798b32bd
commit a7754b05ba
6 changed files with 24 additions and 49 deletions

View file

@ -6,9 +6,9 @@ SHARED_LIB = libsparsemap.so
#CFLAGS = -Wall -Wextra -Wpedantic -Of -std=c11 -Iinclude/ -fPIC
#CFLAGS = -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -fPIC
#CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -O0 -g -std=c11 -Iinclude/ -fPIC
CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -fPIC
#CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -fPIC
#CFLAGS = -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -fPIC
#CFLAGS = -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -fPIC
CFLAGS = -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -fPIC
#CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -Og -g -fsanitize=address,leak,object-size,pointer-compare,pointer-subtract,null,return,bounds,pointer-overflow,undefined -fsanitize-address-use-after-scope -std=c11 -Iinclude/ -fPIC
#CFLAGS = -Wall -Wextra -Wpedantic -Og -g -fsanitize=all -fhardened -std=c11 -Iinclude/ -fPIC
@ -37,6 +37,9 @@ $(SHARED_LIB): $(OBJS)
examples: $(STATIC_LIB) $(EXAMPLES) examples/common.o
soak: examples/soak.c
examples/soak
mls: examples/mls
test: $(TESTS)

View file

@ -538,12 +538,10 @@ verify_sm_is_first_available_span(sparsemap_t *map, sparsemap_idx_t idx, size_t
{
for (sparsemap_idx_t i = 0; i < idx + len; i++) {
sparsemap_idx_t j = 0;
while (sparsemap_is_set(map, i + j) == value && j < len && j < idx + len) {
while (sparsemap_is_set(map, i + j) == value && j < len) {
j++;
}
if (j == len) {
return i == idx;
}
return i == idx;
}
return false;
}
@ -669,7 +667,6 @@ main(void)
assert(_sparsemap_set(&map, pg, true) == pg);
}
mdb_midl_sort(list);
stats(0, map, list);
assert(verify_sm_eq_ml(map, list));
double b, e;
@ -774,8 +771,8 @@ main(void)
assert(verify_sm_eq_ml(map, list));
// Once we've used half of the free list, let's replenish it a bit.
if (list[0] < amt / 2) {
// Once we've used a tenth of the free list, let's replenish it a bit.
if (list[0] < amt / 10) {
do {
pgno_t pgno;
size_t len, retries = amt;
@ -817,7 +814,7 @@ main(void)
// every so often, either ...
if (iterations % 1000 == 0) {
larger_please:;
size_t COUNT = xorshift32() % 1024 + 513;
size_t COUNT = xorshift32() % 3586 + 513;
// ... add some amount of 4KiB pages, or
size_t len = COUNT;
// The largest page is at list[1] because this is a reverse sorted list.
@ -873,8 +870,9 @@ main(void)
}
}
}
iterations++;
stats(iterations, map, list);
// printf("\033[K%zu\r", iterations);
iterations++;
}
return 0;

View file

@ -38,7 +38,6 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#pragma GCC diagnostic ignored "-Wvariadic-macros"
#include <stdarg.h>
#define __sm_diag(format, ...) __sm_diag_(__FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
#pragma GCC diagnostic pop
void __attribute__((format(printf, 4, 5))) __sm_diag_(const char *file, int line, const char *func, const char *format, ...)
@ -236,7 +235,7 @@ __sm_chunk_map_set_capacity(__sm_chunk_t *map, size_t capacity)
size_t reduced = 0;
register uint8_t *p = (uint8_t *)map->m_data;
for (ssize_t i = sizeof(sm_bitvec_t) - 1; i >= 0; i--) { // TODO:
for (ssize_t i = sizeof(sm_bitvec_t) - 1; i >= 0; i--) {
for (int j = SM_FLAGS_PER_INDEX_BYTE - 1; j >= 0; j--) {
p[i] &= ~((sm_bitvec_t)SM_PAYLOAD_ONES << (j * 2));
p[i] |= ((sm_bitvec_t)SM_PAYLOAD_NONE << (j * 2));
@ -1105,7 +1104,7 @@ sparsemap_set(sparsemap_t *map, sparsemap_idx_t idx, bool value)
__sm_append_data(map, &buf[0], sizeof(buf));
uint8_t *p = __sm_get_chunk_map_data(map, 0);
*(sm_idx_t *)p = __sm_get_fully_aligned_offset(idx); // TODO was not fully aligned before... why?
*(sm_idx_t *)p = __sm_get_fully_aligned_offset(idx);
__sm_set_chunk_map_count(map, 1);
@ -1582,18 +1581,18 @@ sparsemap_span(sparsemap_t *map, sparsemap_idx_t idx, size_t len, bool value)
{
size_t rank, nth;
sm_bitvec_t vec = 0;
sparsemap_idx_t offset = 0;
sparsemap_idx_t offset;
/* When skipping forward to `idx` offset in the map we can determine how
many selects we can avoid by taking the rank of the range and starting
at that bit. */
nth = (idx < 1) ? 0 : sparsemap_rank(map, 0, idx - 1, value);
nth = (idx == 0) ? 0 : sparsemap_rank(map, 0, idx - 1, value);
/* Find the first bit that matches value, then... */
offset = sparsemap_select(map, nth, value);
do {
/* See if the rank of the bits in the range starting at offset is equal
to the desired amount. */
rank = len == 1 ? 1 : sparsemap_rank_vec(map, offset, offset + len - 1, value, &vec);
rank = (len == 1) ? 1 : sparsemap_rank_vec(map, offset, offset + len - 1, value, &vec);
if (rank >= len) {
/* We've found what we're looking for, return the index of the first
bit in the range. */
@ -1602,13 +1601,10 @@ sparsemap_span(sparsemap_t *map, sparsemap_idx_t idx, size_t len, bool value)
/* Now we try to jump forward as much as possible before we look for a
new match. We do this by counting the remaining bits in the returned
vec from the call to rank_vec(). */
int amt = 0;
if (vec == 0) {
/* The returned vec had no set bits, let's move forward in the map. */
amt = (rank == 0) ? len : 1;
} else {
/* We might be able to jump forward up to 64 bit positions saving us repeated
calls to select()/rank(). */
int amt = 1;
if (vec > 0) {
/* The returned vec had som set bits, let's move forward in the map as much
as possible (max: 64 bit positions). */
int max = len > SM_BITS_PER_VECTOR ? SM_BITS_PER_VECTOR : len;
while (amt < max && (vec & 1 << amt)) {
amt++;

View file

@ -87,7 +87,7 @@ xorshift32_seed(void)
}
void
shuffle(int *array, size_t n) // TODO working?
shuffle(int *array, size_t n)
{
for (size_t i = n - 1; i > 0; --i) {
size_t j = xorshift32() % (i + 1);

View file

@ -1,4 +1,6 @@
#include "../include/sparsemap.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wvariadic-macros"
#define __diag(...) \

View file

@ -46,7 +46,6 @@ populate_map(sparsemap_t *map, int size, int max_value)
int array[size];
setup_test_array(array, size, max_value);
// TODO ensure_sequential_set(array, size, 10);
shuffle(array, size);
for (int i = 0; i < size; i++) {
sparsemap_set(map, array[i], true);
@ -995,14 +994,6 @@ test_api_span(const MunitParameter params[], void *data)
located_at = sparsemap_span(map, placed_at / 2, 50, true);
assert_true(located_at == placed_at);
/* TODO
sparsemap_clear(map);
placed_at = sm_add_span(map, amt, amt - 1);
located_at = sparsemap_span(map, 0, amt - 1, true);
assert_true(located_at == placed_at);
*/
return MUNIT_OK;
}
@ -1070,7 +1061,6 @@ test_scale_lots_o_spans(const MunitParameter params[], void *data)
for (size_t i = 0; i < amt;) {
int l = i % 31 + 16;
// TODO: sm_add_span(map, amt, l);
sm_add_span(map, 10000, l);
if (errno == ENOSPC) {
map = sparsemap_set_data_size(map, sparsemap_get_capacity(map) * 2, NULL);
@ -1250,8 +1240,6 @@ test_scale_best_case(const MunitParameter params[], void *data)
So, in a 1KiB buffer you have:
(1024 KiB / 8 bytes) * 2048 = 268,435,456 bits
or 1.09 TiB of 4KiB pages. Let's investigate, and find out if that's the case.
TODO: Actually, 172032 are stored before SEGV, or 706 MiB of 4KiB pages.
*/
/* Set every bit on, that should be the best case. */
@ -1296,8 +1284,6 @@ test_scale_worst_case(const MunitParameter params[], void *data)
So, in a 1KiB buffer you have:
(1024 KiB / 264 bytes) * 2048 = 8,134,407.75758 bits
or 33.3 GiB of 4KiB pages. Let's investigate, and find out if that's the case.
TODO: actually 7744 are stored before SEGV, or 31MiB of 4KiB pages.
*/
/* Set every other bit, that has to be the "worst case" for this index. */
@ -1336,26 +1322,16 @@ static MunitResult
test_perf_span_solo(const MunitParameter params[], void *data)
{
sparsemap_t *map = (sparsemap_t *)data;
// double stop, start;
(void)params;
int located_at, placed_at, amt = 500;
assert_ptr_not_null(map);
return MUNIT_OK; // TODO
for (int i = 1; i < amt; i++) {
for (int length = 1; length <= 100; length++) {
sparsemap_clear(map);
placed_at = sm_add_span(map, amt, length);
// logf("i = %d, length = %d\tplaced_at %d\n", i, length, placed_at);
// sm_whats_set(map, 5000);
// start = nsts();
located_at = sparsemap_span(map, 0, length, true);
// stop = nsts();
// double amt = (stop - start) * 1e6;
// if (amt > 0) {
// fprintf(stdout, "%0.8f\n", amt);
// }
if (placed_at != located_at)
logf("a: i = %d, length = %d\tplaced_at %d located_at %d\n", i, length, placed_at, located_at);
}