mirror of
https://github.com/cuberite/libdeflate.git
synced 2025-09-15 07:18:29 -04:00
benchmark: support using guard pages
This commit is contained in:
parent
6a05e63bbb
commit
cfa0f0515d
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "prog_util.h"
|
#include "prog_util.h"
|
||||||
|
|
||||||
static const tchar *const optstring = T("1::2::3::4::5::6::7::8::9::C:D:ghs:VYZz");
|
static const tchar *const optstring = T("1::2::3::4::5::6::7::8::9::C:D:Gghs:VYZz");
|
||||||
|
|
||||||
enum wrapper {
|
enum wrapper {
|
||||||
NO_WRAPPER,
|
NO_WRAPPER,
|
||||||
@ -297,6 +297,14 @@ name_to_engine(const tchar *name)
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
struct chunk_buffers {
|
||||||
|
void *original_buf;
|
||||||
|
void *compressed_buf;
|
||||||
|
void *decompressed_buf;
|
||||||
|
u8 *guarded_buf1_start, *guarded_buf1_end;
|
||||||
|
u8 *guarded_buf2_start, *guarded_buf2_end;
|
||||||
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
compressor_init(struct compressor *c, int level, enum wrapper wrapper,
|
compressor_init(struct compressor *c, int level, enum wrapper wrapper,
|
||||||
const struct engine *engine)
|
const struct engine *engine)
|
||||||
@ -308,10 +316,26 @@ compressor_init(struct compressor *c, int level, enum wrapper wrapper,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
do_compress(struct compressor *c, const void *in, size_t in_nbytes,
|
do_compress(struct compressor *c, struct chunk_buffers *buffers,
|
||||||
void *out, size_t out_nbytes_avail)
|
size_t original_size, size_t max_compressed_size)
|
||||||
{
|
{
|
||||||
return c->engine->compress(c, in, in_nbytes, out, out_nbytes_avail);
|
void *in = buffers->original_buf;
|
||||||
|
void *out = buffers->compressed_buf;
|
||||||
|
size_t compressed_size;
|
||||||
|
|
||||||
|
if (buffers->guarded_buf1_start != NULL) {
|
||||||
|
in = buffers->guarded_buf1_end - original_size;
|
||||||
|
out = buffers->guarded_buf2_end - max_compressed_size;
|
||||||
|
memcpy(in, buffers->original_buf, original_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
compressed_size = c->engine->compress(c, in, original_size,
|
||||||
|
out, max_compressed_size);
|
||||||
|
|
||||||
|
if (out != buffers->compressed_buf)
|
||||||
|
memcpy(buffers->compressed_buf, out, compressed_size);
|
||||||
|
|
||||||
|
return compressed_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -330,10 +354,25 @@ decompressor_init(struct decompressor *d, enum wrapper wrapper,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
do_decompress(struct decompressor *d, const void *in, size_t in_nbytes,
|
do_decompress(struct decompressor *d, struct chunk_buffers *buffers,
|
||||||
void *out, size_t out_nbytes)
|
size_t compressed_size, size_t original_size)
|
||||||
{
|
{
|
||||||
return d->engine->decompress(d, in, in_nbytes, out, out_nbytes);
|
void *in = buffers->compressed_buf;
|
||||||
|
void *out = buffers->decompressed_buf;
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
if (buffers->guarded_buf1_start != NULL) {
|
||||||
|
in = buffers->guarded_buf1_end - compressed_size;
|
||||||
|
out = buffers->guarded_buf2_end - original_size;
|
||||||
|
memcpy(in, buffers->compressed_buf, compressed_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = d->engine->decompress(d, in, compressed_size, out, original_size);
|
||||||
|
|
||||||
|
if (ok && out != buffers->decompressed_buf)
|
||||||
|
memcpy(buffers->decompressed_buf, out, original_size);
|
||||||
|
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -371,6 +410,7 @@ show_usage(FILE *fp)
|
|||||||
" -12 slowest (best) compression\n"
|
" -12 slowest (best) compression\n"
|
||||||
" -C ENGINE compression engine\n"
|
" -C ENGINE compression engine\n"
|
||||||
" -D ENGINE decompression engine\n"
|
" -D ENGINE decompression engine\n"
|
||||||
|
" -G test with guard pages\n"
|
||||||
" -g use gzip wrapper\n"
|
" -g use gzip wrapper\n"
|
||||||
" -h print this help\n"
|
" -h print this help\n"
|
||||||
" -s SIZE chunk size\n"
|
" -s SIZE chunk size\n"
|
||||||
@ -397,10 +437,48 @@ show_version(void)
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
static void free_chunk_buffers(struct chunk_buffers *buffers)
|
||||||
|
{
|
||||||
|
free(buffers->original_buf);
|
||||||
|
free(buffers->compressed_buf);
|
||||||
|
free(buffers->decompressed_buf);
|
||||||
|
free_guarded_buffer(buffers->guarded_buf1_start,
|
||||||
|
buffers->guarded_buf1_end);
|
||||||
|
free_guarded_buffer(buffers->guarded_buf2_start,
|
||||||
|
buffers->guarded_buf2_end);
|
||||||
|
memset(buffers, 0, sizeof(*buffers));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool alloc_chunk_buffers(struct chunk_buffers *buffers,
|
||||||
|
u32 chunk_size, bool use_guard_pages)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
memset(buffers, 0, sizeof(*buffers));
|
||||||
|
|
||||||
|
buffers->original_buf = xmalloc(chunk_size);
|
||||||
|
buffers->compressed_buf = xmalloc(chunk_size - 1);
|
||||||
|
buffers->decompressed_buf = xmalloc(chunk_size);
|
||||||
|
|
||||||
|
if (use_guard_pages) {
|
||||||
|
res |= alloc_guarded_buffer(chunk_size,
|
||||||
|
&buffers->guarded_buf1_start,
|
||||||
|
&buffers->guarded_buf1_end);
|
||||||
|
res |= alloc_guarded_buffer(chunk_size,
|
||||||
|
&buffers->guarded_buf2_start,
|
||||||
|
&buffers->guarded_buf2_end);
|
||||||
|
}
|
||||||
|
if (buffers->original_buf == NULL || buffers->compressed_buf == NULL ||
|
||||||
|
buffers->decompressed_buf == NULL || res != 0) {
|
||||||
|
free_chunk_buffers(buffers);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_benchmark(struct file_stream *in, void *original_buf, void *compressed_buf,
|
do_benchmark(struct file_stream *in, struct chunk_buffers *buffers,
|
||||||
void *decompressed_buf, u32 chunk_size,
|
u32 chunk_size, struct compressor *compressor,
|
||||||
struct compressor *compressor,
|
|
||||||
struct decompressor *decompressor)
|
struct decompressor *decompressor)
|
||||||
{
|
{
|
||||||
u64 total_uncompressed_size = 0;
|
u64 total_uncompressed_size = 0;
|
||||||
@ -409,7 +487,7 @@ do_benchmark(struct file_stream *in, void *original_buf, void *compressed_buf,
|
|||||||
u64 total_decompress_time = 0;
|
u64 total_decompress_time = 0;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
while ((ret = xread(in, original_buf, chunk_size)) > 0) {
|
while ((ret = xread(in, buffers->original_buf, chunk_size)) > 0) {
|
||||||
u32 original_size = ret;
|
u32 original_size = ret;
|
||||||
u32 compressed_size;
|
u32 compressed_size;
|
||||||
u64 start_time;
|
u64 start_time;
|
||||||
@ -419,11 +497,8 @@ do_benchmark(struct file_stream *in, void *original_buf, void *compressed_buf,
|
|||||||
|
|
||||||
/* Compress the chunk of data. */
|
/* Compress the chunk of data. */
|
||||||
start_time = timer_ticks();
|
start_time = timer_ticks();
|
||||||
compressed_size = do_compress(compressor,
|
compressed_size = do_compress(compressor, buffers,
|
||||||
original_buf,
|
original_size, original_size - 1);
|
||||||
original_size,
|
|
||||||
compressed_buf,
|
|
||||||
original_size - 1);
|
|
||||||
total_compress_time += timer_ticks() - start_time;
|
total_compress_time += timer_ticks() - start_time;
|
||||||
|
|
||||||
if (compressed_size) {
|
if (compressed_size) {
|
||||||
@ -432,9 +507,8 @@ do_benchmark(struct file_stream *in, void *original_buf, void *compressed_buf,
|
|||||||
/* Decompress the data we just compressed and compare
|
/* Decompress the data we just compressed and compare
|
||||||
* the result with the original. */
|
* the result with the original. */
|
||||||
start_time = timer_ticks();
|
start_time = timer_ticks();
|
||||||
ok = do_decompress(decompressor,
|
ok = do_decompress(decompressor, buffers,
|
||||||
compressed_buf, compressed_size,
|
compressed_size, original_size);
|
||||||
decompressed_buf, original_size);
|
|
||||||
total_decompress_time += timer_ticks() - start_time;
|
total_decompress_time += timer_ticks() - start_time;
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
@ -443,7 +517,8 @@ do_benchmark(struct file_stream *in, void *original_buf, void *compressed_buf,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(original_buf, decompressed_buf,
|
if (memcmp(buffers->original_buf,
|
||||||
|
buffers->decompressed_buf,
|
||||||
original_size) != 0)
|
original_size) != 0)
|
||||||
{
|
{
|
||||||
msg("%"TS": data did not decompress to "
|
msg("%"TS": data did not decompress to "
|
||||||
@ -495,12 +570,11 @@ tmain(int argc, tchar *argv[])
|
|||||||
enum wrapper wrapper = NO_WRAPPER;
|
enum wrapper wrapper = NO_WRAPPER;
|
||||||
const struct engine *compress_engine = &DEFAULT_ENGINE;
|
const struct engine *compress_engine = &DEFAULT_ENGINE;
|
||||||
const struct engine *decompress_engine = &DEFAULT_ENGINE;
|
const struct engine *decompress_engine = &DEFAULT_ENGINE;
|
||||||
void *original_buf = NULL;
|
struct chunk_buffers buffers;
|
||||||
void *compressed_buf = NULL;
|
|
||||||
void *decompressed_buf = NULL;
|
|
||||||
struct compressor compressor;
|
struct compressor compressor;
|
||||||
struct decompressor decompressor;
|
struct decompressor decompressor;
|
||||||
tchar *default_file_list[] = { NULL };
|
tchar *default_file_list[] = { NULL };
|
||||||
|
bool use_guard_pages = false;
|
||||||
int opt_char;
|
int opt_char;
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
@ -538,6 +612,9 @@ tmain(int argc, tchar *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'G':
|
||||||
|
use_guard_pages = true;
|
||||||
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
wrapper = GZIP_WRAPPER;
|
wrapper = GZIP_WRAPPER;
|
||||||
break;
|
break;
|
||||||
@ -572,13 +649,9 @@ tmain(int argc, tchar *argv[])
|
|||||||
argc -= toptind;
|
argc -= toptind;
|
||||||
argv += toptind;
|
argv += toptind;
|
||||||
|
|
||||||
original_buf = xmalloc(chunk_size);
|
|
||||||
compressed_buf = xmalloc(chunk_size - 1);
|
|
||||||
decompressed_buf = xmalloc(chunk_size);
|
|
||||||
|
|
||||||
ret = -1;
|
ret = -1;
|
||||||
if (original_buf == NULL || compressed_buf == NULL ||
|
|
||||||
decompressed_buf == NULL)
|
if (!alloc_chunk_buffers(&buffers, chunk_size, use_guard_pages))
|
||||||
goto out0;
|
goto out0;
|
||||||
|
|
||||||
if (!compressor_init(&compressor, level, wrapper, compress_engine))
|
if (!compressor_init(&compressor, level, wrapper, compress_engine))
|
||||||
@ -604,6 +677,8 @@ tmain(int argc, tchar *argv[])
|
|||||||
wrapper == ZLIB_WRAPPER ? "zlib" : "gzip");
|
wrapper == ZLIB_WRAPPER ? "zlib" : "gzip");
|
||||||
printf("\tCompression engine: %"TS"\n", compress_engine->name);
|
printf("\tCompression engine: %"TS"\n", compress_engine->name);
|
||||||
printf("\tDecompression engine: %"TS"\n", decompress_engine->name);
|
printf("\tDecompression engine: %"TS"\n", decompress_engine->name);
|
||||||
|
if (use_guard_pages)
|
||||||
|
printf("\tDebugging options: guard_pages\n");
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
struct file_stream in;
|
struct file_stream in;
|
||||||
@ -614,8 +689,7 @@ tmain(int argc, tchar *argv[])
|
|||||||
|
|
||||||
printf("Processing %"TS"...\n", in.name);
|
printf("Processing %"TS"...\n", in.name);
|
||||||
|
|
||||||
ret = do_benchmark(&in, original_buf, compressed_buf,
|
ret = do_benchmark(&in, &buffers, chunk_size, &compressor,
|
||||||
decompressed_buf, chunk_size, &compressor,
|
|
||||||
&decompressor);
|
&decompressor);
|
||||||
xclose(&in);
|
xclose(&in);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
@ -627,8 +701,6 @@ out2:
|
|||||||
out1:
|
out1:
|
||||||
compressor_destroy(&compressor);
|
compressor_destroy(&compressor);
|
||||||
out0:
|
out0:
|
||||||
free(decompressed_buf);
|
free_chunk_buffers(&buffers);
|
||||||
free(compressed_buf);
|
|
||||||
free(original_buf);
|
|
||||||
return -ret;
|
return -ret;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user