From a39e892f3b809e4a7d87a28a41fc5e7e2796c3cb Mon Sep 17 00:00:00 2001 From: Lars Quentin Date: Mon, 26 Feb 2024 12:12:45 +0100 Subject: [PATCH] new benchmark pattern: reverse read! --- .../src/c_code/benchmarker.h | 3 + .../src/c_code/benchmarker_internal.c | 35 +++++++++++ .../src/c_code/sanitizer_tests/Makefile | 2 +- .../src/c_code/sanitizer_tests/san_test.c | 62 ++++++++++++++++++- 4 files changed, 100 insertions(+), 2 deletions(-) diff --git a/blackheap-benchmarker/src/c_code/benchmarker.h b/blackheap-benchmarker/src/c_code/benchmarker.h index 6257a60..d5b1c66 100644 --- a/blackheap-benchmarker/src/c_code/benchmarker.h +++ b/blackheap-benchmarker/src/c_code/benchmarker.h @@ -15,6 +15,7 @@ enum access_pattern { ACCESS_PATTERN_CONST = 0, ACCESS_PATTERN_SEQUENTIAL = 1, ACCESS_PATTERN_RANDOM = 2, + ACCESS_PATTERN_REVERSE = 3, }; enum error_codes { @@ -36,6 +37,8 @@ enum error_codes { ERROR_CODES_DROP_PAGE_CACHE_FAILED_OTHER = 11, ERROR_CODES_INCORRECT_FILE_BUFFER_SIZE = 12, + + ERROR_CODES_TOO_SMALL_FILE_BUFFER = 13, }; diff --git a/blackheap-benchmarker/src/c_code/benchmarker_internal.c b/blackheap-benchmarker/src/c_code/benchmarker_internal.c index 95c0a2e..3d3176d 100644 --- a/blackheap-benchmarker/src/c_code/benchmarker_internal.c +++ b/blackheap-benchmarker/src/c_code/benchmarker_internal.c @@ -304,6 +304,17 @@ void pick_next_mem_position(const struct benchmark_config *config, struct benchm case ACCESS_PATTERN_RANDOM: state->last_mem_offset = ((size_t)rand() * 128) % (config->memory_buffer_in_bytes - config->access_size_in_bytes); return; + case ACCESS_PATTERN_REVERSE: { + /* we only have to move one back since it didnt update since the last read. */ + + /* Check for wrapping */ + if (state->last_mem_offset < config->access_size_in_bytes) { + state->last_mem_offset = config->memory_buffer_in_bytes - config->access_size_in_bytes; + } else { + state->last_mem_offset -= config->access_size_in_bytes; + } + return; + } } } @@ -349,6 +360,30 @@ enum error_codes pick_next_file_position(const struct benchmark_config *config, } } break; + case ACCESS_PATTERN_REVERSE: { + /* two access sizes since we need one to go back to the last read, and one more to go backwards */ + + /* check for wrapping */ + if (state->last_file_offset < 2 * config->access_size_in_bytes) { + /* Do we even have enough space to move back 2 access sizes? */ + if (config->file_size_in_bytes > 2 * config->access_size_in_bytes) { + state->last_file_offset = config->file_size_in_bytes - config->access_size_in_bytes; + } else { + fprintf(stderr, "File size %zu is too small for reverse access pattern with %zu access size.\n", config->file_size_in_bytes, config->access_size_in_bytes); + return ERROR_CODES_TOO_SMALL_FILE_BUFFER; + } + } else { + state->last_file_offset -= 2 * config->access_size_in_bytes; + } + + /* Update file descriptor */ + off_t new_offset = lseek(state->fd, state->last_file_offset, SEEK_SET); + if (new_offset == -1) { + fprintf(stderr, "Failed to seek \"%s\" to 0. \nError: %s\n", config->filepath, strerror(errno)); + return ERROR_CODES_LSEEK_FAILED; + } + } + break; } return ERROR_CODES_SUCCESS; } diff --git a/blackheap-benchmarker/src/c_code/sanitizer_tests/Makefile b/blackheap-benchmarker/src/c_code/sanitizer_tests/Makefile index 36e1d2c..b14e494 100644 --- a/blackheap-benchmarker/src/c_code/sanitizer_tests/Makefile +++ b/blackheap-benchmarker/src/c_code/sanitizer_tests/Makefile @@ -1,7 +1,7 @@ all: clean build_asan build_ubsan clean: - rm *.exe + rm -f *.exe build_asan: clang -Wall -Wextra -fsanitize=address -g san_test.c ../benchmarker_internal.c -o benchmark_test_asan.exe diff --git a/blackheap-benchmarker/src/c_code/sanitizer_tests/san_test.c b/blackheap-benchmarker/src/c_code/sanitizer_tests/san_test.c index 76ae5a3..86f2fac 100644 --- a/blackheap-benchmarker/src/c_code/sanitizer_tests/san_test.c +++ b/blackheap-benchmarker/src/c_code/sanitizer_tests/san_test.c @@ -24,6 +24,21 @@ void run_benchmark(struct benchmark_config config, const char *description) { } int main() { + run_benchmark((struct benchmark_config){ + .filepath = "/tmp/test_file.bin", + .memory_buffer_in_bytes = 1024, + .file_size_in_bytes = 1024 * 10, + .access_size_in_bytes = 128, + .number_of_io_op_tests = 10, + .access_pattern_in_memory = ACCESS_PATTERN_CONST, + .access_pattern_in_file = ACCESS_PATTERN_CONST, + .is_read_operation = true, + .prepare_file_size = true, + .drop_cache_first = false, + .do_reread = false, + .restrict_free_ram_to = 0 + }, "Simple Test (const)"); + run_benchmark((struct benchmark_config){ .filepath = "/tmp/test_file.bin", .memory_buffer_in_bytes = 1024, @@ -37,7 +52,37 @@ int main() { .drop_cache_first = false, .do_reread = false, .restrict_free_ram_to = 0 - }, "Simple Test"); + }, "Simple Test (seq)"); + + run_benchmark((struct benchmark_config){ + .filepath = "/tmp/test_file.bin", + .memory_buffer_in_bytes = 1024, + .file_size_in_bytes = 1024 * 10, + .access_size_in_bytes = 128, + .number_of_io_op_tests = 10, + .access_pattern_in_memory = ACCESS_PATTERN_RANDOM, + .access_pattern_in_file = ACCESS_PATTERN_RANDOM, + .is_read_operation = true, + .prepare_file_size = true, + .drop_cache_first = false, + .do_reread = false, + .restrict_free_ram_to = 0 + }, "Simple Test (rnd)"); + + run_benchmark((struct benchmark_config){ + .filepath = "/tmp/test_file.bin", + .memory_buffer_in_bytes = 1024, + .file_size_in_bytes = 1024 * 10, + .access_size_in_bytes = 128, + .number_of_io_op_tests = 10, + .access_pattern_in_memory = ACCESS_PATTERN_REVERSE, + .access_pattern_in_file = ACCESS_PATTERN_REVERSE, + .is_read_operation = true, + .prepare_file_size = true, + .drop_cache_first = false, + .do_reread = false, + .restrict_free_ram_to = 0 + }, "Simple Test (rev)"); run_benchmark((struct benchmark_config){ .filepath = "/tmp/test_file.bin", @@ -84,6 +129,21 @@ int main() { .restrict_free_ram_to = 0 }, "Can it handle wrapping (rnd)"); + run_benchmark((struct benchmark_config){ + .filepath = "/tmp/test_file.bin", + .memory_buffer_in_bytes = 1024 * 512, // 512KB + .file_size_in_bytes = 1024 * 512, // 512KB + .access_size_in_bytes = 1024 * 300, // 300KB + .number_of_io_op_tests = 10, + .access_pattern_in_memory = ACCESS_PATTERN_REVERSE, + .access_pattern_in_file = ACCESS_PATTERN_REVERSE, + .is_read_operation = true, + .prepare_file_size = true, + .drop_cache_first = false, + .do_reread = false, + .restrict_free_ram_to = 0 + }, "Can it handle wrapping (rev)"); + run_benchmark((struct benchmark_config){ .filepath = "/tmp/test_file.bin", .memory_buffer_in_bytes = 1024, // 1KB