#include #include #include #include #include "utils.c" #include "repetition_tester.c" static void read_malloc_file_with_fread(bool should_alloc, struct repetitor *repetitor, uint8_t *buffer, uint64_t buffer_size, char *filename) { alloc_buffer(should_alloc, &buffer, buffer_size); FILE *file = fopen(filename, "r"); uint64_t read_amount = 0; while (read_amount < buffer_size) { repetitor_measure_start(repetitor); int result = fread(&buffer[read_amount], 1, buffer_size - read_amount, file); repetitor_measure_stop(repetitor, result > 0 ? result : 0); if (result <= 0) { printf("ERROR: Failed to read from file\n"); break; } read_amount += result; } fclose(file); free_buffer(should_alloc, buffer); } static void read_malloc_file_with_read(bool should_alloc, struct repetitor *repetitor, uint8_t *buffer, uint64_t buffer_size, char *filename) { alloc_buffer(should_alloc, &buffer, buffer_size); int file = open(filename, O_RDONLY); uint64_t read_amount = 0; while (read_amount < buffer_size) { repetitor_measure_start(repetitor); int result = read(file, &buffer[read_amount], buffer_size - read_amount); repetitor_measure_stop(repetitor, result > 0 ? result : 0); if (result <= 0) { printf("ERROR: Failed to read from file\n"); break; } read_amount += result; } close(file); free_buffer(should_alloc, buffer); } int main_test_malloc_read(char *filename) { typedef void (*read_file_b)(bool should_alloc, struct repetitor *repetitor, uint8_t *buffer, uint64_t buffer_size, char *filename); struct testcase { char *name; read_file_b cb; }; struct testcase cases[] = { { .name = "read()", .cb = read_malloc_file_with_fread }, { .name = "fread()", .cb = read_malloc_file_with_read }, }; struct repetitor repetitor = {}; repetitor_init(&repetitor); printf("CPU Frequency: %ldHz (~%.2fGHz)\n", repetitor.cpu_freq, (float)repetitor.cpu_freq/(1000*1000*1000)); uint64_t file_size = get_file_size(filename); uint8_t *buffer = malloc(sizeof(uint8_t) * file_size); memset(buffer, 0, file_size); // Touch memory, so OS would be forced to page in the memory while (repeat_cycle_times(&repetitor, 3)) { for (int i = 0; i < ARRAY_LEN(cases); i++) { struct testcase *testcase = &cases[i]; // With malloc { repetitor_clear(&repetitor); while (repetitor_repeat(&repetitor, 3)) { repetitor_start(&repetitor); testcase->cb(true, &repetitor, buffer, file_size, filename); repetitor_stop(&repetitor); } char label[256]; snprintf(label, sizeof(label), "%s + malloc", testcase->name); repetitor_print_results_label(&repetitor, label); } // Without malloc { repetitor_clear(&repetitor); while (repetitor_repeat(&repetitor, 1)) { repetitor_start(&repetitor); testcase->cb(false, &repetitor, buffer, file_size, filename); repetitor_stop(&repetitor); } char label[256]; snprintf(label, sizeof(label), "%s + no malloc", testcase->name); repetitor_print_results_label(&repetitor, label); } } } return 0; }