diff --git a/benches/bench_rt.toml b/benches/bench_rt.toml index ca40befe..0ecfa7aa 100644 --- a/benches/bench_rt.toml +++ b/benches/bench_rt.toml @@ -28,64 +28,87 @@ code = ''' [cases.bench_rt_seq] code = ''' lfs3_t lfs3; + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0; if (!SKIP_WARMUP) { - BENCH_PAUSE(); + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); int err = bench_helpers_warmup(&lfs3); if (err) { LFS3_ERROR("Bench warmup failed: %d", err); return; } - BENCH_RESUME(); + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); } uint32_t prng = SEED; // reset our timer BENCH_SIMRESET(); - // create a file to read - lfs3_file_t file; - lfs3_file_open(&lfs3, &file, "bench_linear", + // open a file for both writing and reading + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + lfs3_file_t wfile; + lfs3_file_open(&lfs3, &wfile, "bench_seq", LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0; - for (lfs3_size_t i = 0; i < (SIZE+(CHUNK-1))/CHUNK; i++) { - uint8_t wbuf[CHUNK]; - for (lfs3_size_t j = 0; j < CHUNK; j++) { - wbuf[j] = 'a' + (BENCH_PRNG(&prng) % 26); - } - lfs3_file_write(&lfs3, &file, wbuf, CHUNK) => CHUNK; - - // taking too long? - if (SIM_TIME && BENCH_SIMTIME() >= SIM_TIME) { - return; - } - } - lfs3_file_close(&lfs3, &file) => 0; - - // reset our timer - BENCH_SIMRESET(); - - // open the file + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); BENCH_START("read"); - lfs3_file_open(&lfs3, &file, "bench_linear", LFS3_O_RDONLY) => 0; + lfs3_file_t rfile; + lfs3_file_open(&lfs3, &rfile, "bench_seq", + LFS3_O_RDONLY) => 0; lfs3_off_t size = 0; + lfs3_off_t readed_ = 0; uint64_t readed = 0; + BENCH_STOP("read", readed); + // ok, one of these needs to be non-zero + LFS3_ASSERT(SIM_TIME > 0 || SIM_SIZE > 0); while (!(SIM_SIZE && readed >= (uint64_t)SIM_SIZE) && !(SIM_TIME && BENCH_SIMTIME() >= SIM_TIME)) { + // gradually increase the file size, so we at least have somewhat + // meaningful results if we timeout early + if (size < SIZE) { + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + uint8_t wbuf[CHUNK]; + for (lfs3_size_t j = 0; j < CHUNK; j++) { + wbuf[j] = 'a' + (BENCH_PRNG(&prng) % 26); + } + lfs3_file_write(&lfs3, &wfile, wbuf, CHUNK) => CHUNK; + lfs3_file_sync(&lfs3, &wfile) => 0; + + size += CHUNK; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); + } + + BENCH_START("read"); + // rewind if we reach the end + if (readed_ >= size) { + lfs3_file_rewind(&lfs3, &rfile) => 0; + readed_ = 0; + } + // read from the file uint8_t rbuf[CHUNK]; - lfs3_file_read(&lfs3, &file, rbuf, CHUNK) => CHUNK; + lfs3_file_read(&lfs3, &rfile, rbuf, CHUNK) => CHUNK; - size += CHUNK; + readed_ += CHUNK; readed += CHUNK; - - // rewind if we reach the end - if (size >= SIZE) { - lfs3_file_rewind(&lfs3, &file) => 0; - size = 0; - } + BENCH_STOP("read", readed); } - lfs3_file_close(&lfs3, &file) => 0; + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + lfs3_file_close(&lfs3, &wfile) => 0; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); + BENCH_START("read"); + lfs3_file_close(&lfs3, &rfile) => 0; // report the amount we managed to read BENCH_STOP("read", readed); @@ -96,60 +119,176 @@ code = ''' [cases.bench_rt_random] code = ''' lfs3_t lfs3; + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0; if (!SKIP_WARMUP) { - BENCH_PAUSE(); + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); int err = bench_helpers_warmup(&lfs3); if (err) { return; } - BENCH_RESUME(); + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); } uint32_t prng = SEED; // reset our timer BENCH_SIMRESET(); - // create a file to read - lfs3_file_t file; - lfs3_file_open(&lfs3, &file, "bench_random", + // open a file for both writing and reading + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + lfs3_file_t wfile; + lfs3_file_open(&lfs3, &wfile, "bench_random", LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0; - for (lfs3_size_t i = 0; i < (SIZE+(CHUNK-1))/CHUNK; i++) { - uint8_t wbuf[CHUNK]; - for (lfs3_size_t j = 0; j < CHUNK; j++) { - wbuf[j] = 'a' + (BENCH_PRNG(&prng) % 26); - } - lfs3_file_write(&lfs3, &file, wbuf, CHUNK) => CHUNK; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); + BENCH_START("read"); + lfs3_file_t rfile; + lfs3_file_open(&lfs3, &rfile, "bench_random", + LFS3_O_RDONLY) => 0; + lfs3_off_t size = 0; + uint64_t readed = 0; + BENCH_STOP("read", readed); + // ok, one of these needs to be non-zero + LFS3_ASSERT(SIM_TIME > 0 || SIM_SIZE > 0); + while (!(SIM_SIZE && readed >= (uint64_t)SIM_SIZE) + && !(SIM_TIME && BENCH_SIMTIME() >= SIM_TIME)) { + // gradually increase the file size, so we at least have somewhat + // meaningful results if we timeout early + if (size < SIZE) { + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + uint8_t wbuf[CHUNK]; + for (lfs3_size_t j = 0; j < CHUNK; j++) { + wbuf[j] = 'a' + (BENCH_PRNG(&prng) % 26); + } + lfs3_file_write(&lfs3, &wfile, wbuf, CHUNK) => CHUNK; + lfs3_file_sync(&lfs3, &wfile) => 0; - // taking too long? - if (SIM_TIME && BENCH_SIMTIME() >= SIM_TIME) { + size += CHUNK; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); + } + + BENCH_START("read"); + // seek to a random location + lfs3_off_t pos = BENCH_PRNG(&prng) % SIZE; + lfs3_file_seek(&lfs3, &rfile, pos, LFS3_SEEK_SET) => pos; + + // read from the file + uint8_t rbuf[CHUNK]; + lfs3_ssize_t d = lfs3_file_read(&lfs3, &rfile, rbuf, CHUNK); + assert(d <= CHUNK); + + readed += CHUNK; + BENCH_STOP("read", readed); + } + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + lfs3_file_close(&lfs3, &wfile) => 0; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); + BENCH_START("read"); + lfs3_file_close(&lfs3, &rfile) => 0; + // report the amount we managed to read + BENCH_STOP("read", readed); + + lfs3_unmount(&lfs3) => 0; +''' + +# logging read throughput +# +# note this will write as we need to pop the most recent read off the file! +[cases.bench_rt_logging] +code = ''' + lfs3_t lfs3; + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); + lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0; + if (!SKIP_WARMUP) { + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + int err = bench_helpers_warmup(&lfs3); + if (err) { return; } + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); } - lfs3_file_close(&lfs3, &file) => 0; + uint32_t prng = SEED; // reset our timer BENCH_SIMRESET(); - // open the file + // open a file for both writing and reading + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + lfs3_file_t wfile; + lfs3_file_open(&lfs3, &wfile, "bench_random", + LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL | LFS3_O_APPEND) => 0; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); BENCH_START("read"); - lfs3_file_open(&lfs3, &file, "bench_random", LFS3_O_RDONLY) => 0; + lfs3_file_t rfile; + lfs3_file_open(&lfs3, &rfile, "bench_random", + LFS3_O_RDWR) => 0; + lfs3_off_t size = 0; uint64_t readed = 0; + BENCH_STOP("read", readed); + // ok, one of these needs to be non-zero + LFS3_ASSERT(SIM_TIME > 0 || SIM_SIZE > 0); while (!(SIM_SIZE && readed >= (uint64_t)SIM_SIZE) && !(SIM_TIME && BENCH_SIMTIME() >= SIM_TIME)) { - // seek to a random location - lfs3_off_t pos = BENCH_PRNG(&prng) % SIZE; - lfs3_file_seek(&lfs3, &file, pos, LFS3_SEEK_SET) => pos; + // gradually increase the file size, so we at least have somewhat + // meaningful results if we timeout early + // + // note we need to write ~2x to keep up with the reader! + if (size < SIZE) { + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + uint8_t wbuf[CHUNK]; + for (lfs3_size_t j_ = 0; j_ < 2; j_++) { + for (lfs3_size_t j = 0; j < CHUNK; j++) { + wbuf[j] = 'a' + (BENCH_PRNG(&prng) % 26); + } + lfs3_file_write(&lfs3, &wfile, wbuf, CHUNK) => CHUNK; + } + lfs3_file_sync(&lfs3, &wfile) => 0; + size += 2*CHUNK; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); + } + + BENCH_START("read"); // read from the file uint8_t rbuf[CHUNK]; - lfs3_ssize_t d = lfs3_file_read(&lfs3, &file, rbuf, CHUNK); - assert(d <= CHUNK); + lfs3_file_read(&lfs3, &rfile, rbuf, CHUNK) => CHUNK; + // fruncate front of file + lfs3_file_fruncate(&lfs3, &rfile, size-CHUNK) => 0; + // broadcast to writer + lfs3_file_sync(&lfs3, &rfile) => 0; + size -= CHUNK; readed += CHUNK; + BENCH_STOP("read", readed); } - lfs3_file_close(&lfs3, &file) => 0; + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + lfs3_file_close(&lfs3, &wfile) => 0; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); + BENCH_START("read"); + lfs3_file_close(&lfs3, &rfile) => 0; // report the amount we managed to read BENCH_STOP("read", readed); @@ -162,52 +301,66 @@ defines.FILE_SIZE = 'CHUNK' defines.FILE_COUNT = '(SIZE+(FILE_SIZE-1)) / lfs3_max(FILE_SIZE, 1)' code = ''' lfs3_t lfs3; + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0; if (!SKIP_WARMUP) { - BENCH_PAUSE(); + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); int err = bench_helpers_warmup(&lfs3); if (err) { return; } - BENCH_RESUME(); + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); } uint32_t prng = SEED; // reset our timer BENCH_SIMRESET(); - // create files to read - for (lfs3_size_t i = 0; i < (SIZE+(CHUNK-1))/CHUNK; i++) { - char name[256]; - sprintf(name, "bench_%08x", i); - lfs3_file_t file; - lfs3_file_open(&lfs3, &file, name, - LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0; - for (lfs3_size_t i = 0; i < (FILE_SIZE+(CHUNK-1))/CHUNK; i++) { - lfs3_ssize_t d = lfs3_min(CHUNK, FILE_SIZE); - uint8_t wbuf[CHUNK]; - memset(wbuf, 'a'+(BENCH_PRNG(&prng) % 26), d); - lfs3_file_write(&lfs3, &file, wbuf, d) => d; - - // taking too long? - if (SIM_TIME && BENCH_SIMTIME() >= SIM_TIME) { - return; - } - } - lfs3_file_close(&lfs3, &file) => 0; - } - - // reset our timer - BENCH_SIMRESET(); - - // open the files BENCH_START("read"); + lfs3_off_t size = 0; uint64_t readed = 0; + BENCH_STOP("read", readed); + // ok, one of these needs to be non-zero + LFS3_ASSERT(SIM_TIME > 0 || SIM_SIZE > 0); while (!(SIM_SIZE && readed >= (uint64_t)SIM_SIZE) && !(SIM_TIME && BENCH_SIMTIME() >= SIM_TIME)) { + // gradually increase the filesystem size, so we at least have + // somewhat meaningful results if we timeout early + if (size < SIZE) { + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); + char name[256]; + sprintf(name, "bench_%08x", (lfs3_off_t)(size/CHUNK)); + lfs3_file_t wfile; + lfs3_file_open(&lfs3, &wfile, name, + LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0; + for (lfs3_size_t i = 0; i < (FILE_SIZE+(CHUNK-1))/CHUNK; i++) { + lfs3_ssize_t d = lfs3_min(CHUNK, FILE_SIZE); + uint8_t wbuf[CHUNK]; + memset(wbuf, 'a'+(BENCH_PRNG(&prng) % 26), d); + lfs3_file_write(&lfs3, &wfile, wbuf, d) => d; + + // taking too long? + if (SIM_TIME && BENCH_SIMTIME() >= SIM_TIME) { + break; + } + } + lfs3_file_close(&lfs3, &wfile) => 0; + + size += CHUNK; + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); + } + + BENCH_START("read"); // choose a random filename - lfs3_off_t pos = BENCH_PRNG(&prng) % ((SIZE+(CHUNK-1))/CHUNK); + lfs3_off_t pos = BENCH_PRNG(&prng) % ((size+(CHUNK-1))/CHUNK); char name[256]; sprintf(name, "bench_%08x", pos); uint8_t rbuf[CHUNK]; @@ -216,11 +369,11 @@ code = ''' // // note file == CHUNK here, the sum of all files should add up // roughly to the benchmark SIZE - lfs3_file_t file; - lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0; + lfs3_file_t rfile; + lfs3_file_open(&lfs3, &rfile, name, LFS3_O_RDONLY) => 0; for (lfs3_size_t i = 0; i < (FILE_SIZE+(CHUNK-1))/CHUNK; i++) { lfs3_ssize_t d = lfs3_min(CHUNK, FILE_SIZE); - lfs3_file_read(&lfs3, &file, rbuf, d) => d; + lfs3_file_read(&lfs3, &rfile, rbuf, d) => d; readed += d; // taking too long? @@ -228,8 +381,10 @@ code = ''' break; } } - lfs3_file_close(&lfs3, &file) => 0; + lfs3_file_close(&lfs3, &rfile) => 0; + BENCH_STOP("read", readed); } + BENCH_START("read"); // report the amount we managed to read BENCH_STOP("read", readed); diff --git a/benches/bench_wt.toml b/benches/bench_wt.toml index c42d3d25..1da6b457 100644 --- a/benches/bench_wt.toml +++ b/benches/bench_wt.toml @@ -31,13 +31,15 @@ code = ''' lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0; if (!SKIP_WARMUP) { - BENCH_PAUSE(); + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); int err = bench_helpers_warmup(&lfs3); if (err) { LFS3_ERROR("Bench warmup failed: %d", err); return; } - BENCH_RESUME(); + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); } uint32_t prng = SEED; @@ -47,14 +49,16 @@ code = ''' // open a file BENCH_START("write"); lfs3_file_t file; - lfs3_file_open(&lfs3, &file, "bench_linear", + lfs3_file_open(&lfs3, &file, "bench_seq", LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0; lfs3_off_t size = 0; uint64_t written = 0; + BENCH_STOP("write", written); // ok, one of these needs to be non-zero LFS3_ASSERT(SIM_TIME > 0 || SIM_SIZE > 0); while (!(SIM_SIZE && written >= (uint64_t)SIM_SIZE) && !(SIM_TIME && BENCH_SIMTIME() >= SIM_TIME)) { + BENCH_START("write"); // arguably we should just rewind and continue writing to the // front of the file when we hit the end, but this overly // penalizes littlefs2, so instead we truncate @@ -73,7 +77,9 @@ code = ''' size += CHUNK; written += CHUNK; + BENCH_STOP("write", written); } + BENCH_START("write"); lfs3_file_close(&lfs3, &file) => 0; // report the amount we managed to write BENCH_STOP("write", written); @@ -102,12 +108,14 @@ code = ''' lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0; if (!SKIP_WARMUP) { - BENCH_PAUSE(); + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); int err = bench_helpers_warmup(&lfs3); if (err) { return; } - BENCH_RESUME(); + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); } uint32_t prng = SEED; @@ -121,8 +129,12 @@ code = ''' LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0; lfs3_off_t size = 0; uint64_t written = 0; + BENCH_STOP("write", written); + // ok, one of these needs to be non-zero + LFS3_ASSERT(SIM_TIME > 0 || SIM_SIZE > 0); while (!(SIM_SIZE && written >= (uint64_t)SIM_SIZE) && !(SIM_TIME && BENCH_SIMTIME() >= SIM_TIME)) { + BENCH_START("write"); // seek to a random location lfs3_off_t pos = BENCH_PRNG(&prng) % SIZE; lfs3_file_seek(&lfs3, &file, pos, LFS3_SEEK_SET) => pos; @@ -136,7 +148,9 @@ code = ''' size = lfs3_max(size, pos + CHUNK); written += CHUNK; + BENCH_STOP("write", written); } + BENCH_START("write"); lfs3_file_close(&lfs3, &file) => 0; // report the amount we managed to write BENCH_STOP("write", written); @@ -168,12 +182,14 @@ code = ''' lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0; if (!SKIP_WARMUP) { - BENCH_PAUSE(); + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); int err = bench_helpers_warmup(&lfs3); if (err) { return; } - BENCH_RESUME(); + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); } uint32_t prng = SEED; @@ -186,10 +202,12 @@ code = ''' lfs3_file_open(&lfs3, &file, "bench_log", LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL | LFS3_O_APPEND) => 0; uint64_t written = 0; + BENCH_STOP("write", written); // ok, one of these needs to be non-zero LFS3_ASSERT(SIM_TIME > 0 || SIM_SIZE > 0); while (!(SIM_SIZE && written >= (uint64_t)SIM_SIZE) && !(SIM_TIME && BENCH_SIMTIME() >= SIM_TIME)) { + BENCH_START("write"); // append to log uint8_t wbuf[CHUNK]; for (lfs3_size_t j = 0; j < CHUNK; j++) { @@ -218,7 +236,9 @@ code = ''' } written += CHUNK; + BENCH_STOP("write", written); } + BENCH_START("write"); lfs3_file_close(&lfs3, &file) => 0; // report the amount we managed to write BENCH_STOP("write", written); @@ -247,25 +267,28 @@ code = ''' lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0; if (!SKIP_WARMUP) { - BENCH_PAUSE(); + BENCH_STACK_PAUSE(); + BENCH_HEAP_PAUSE(); int err = bench_helpers_warmup(&lfs3); if (err) { return; } - BENCH_RESUME(); + BENCH_HEAP_RESUME(); + BENCH_STACK_RESUME(); } uint32_t prng = SEED; // reset our timer BENCH_SIMRESET(); - // open a file BENCH_START("write"); uint64_t written = 0; + BENCH_STOP("write", written); // ok, one of these needs to be non-zero LFS3_ASSERT(SIM_TIME > 0 || SIM_SIZE > 0); while (!(SIM_SIZE && written >= (uint64_t)SIM_SIZE) && !(SIM_TIME && BENCH_SIMTIME() >= SIM_TIME)) { + BENCH_START("write"); // choose a random filename lfs3_off_t pos = BENCH_PRNG(&prng) % FILE_COUNT; char name[256]; @@ -292,7 +315,9 @@ code = ''' } } lfs3_file_close(&lfs3, &file) => 0; + BENCH_STOP("write", written); } + BENCH_START("write"); // report the amount we managed to write BENCH_STOP("write", written);