This allows ZSTD instead of ZLIB to be used for compressing the shader cache. On a 72 core system emulating skl with a full shader-db (with i965): ZSTD: 1915.10s user 229.27s system 5150% cpu 41.632 total (cold cache) 225.40s user 10.87s system 3810% cpu 6.201 total (warm cache) 154M (235M on disk) ZLIB: 2231.33s user 194.24s system 1899% cpu 2:07.72 total (cold cache) 229.15s user 10.63s system 3906% cpu 6.139 total (warm cache) 163M (244M on disk) Tim Arceri sees (8 core ryzen and a full shader-db): ZSTD: 2505.22 user 40.50 system 3:18.73 elapsed 1280% CPU (cold cache) 418.71 user 14.93 system 0:46.53 elapsed 931% CPU (warm cache) 454.3 MB (681.7 MB on disk) ZLIB: 3069.83 user 40.02 system 4:20.13 elapsed 1195% CPU (cold cache) 425.50 user 15.17 system 0:46.80 elapsed 941% CPU (warm cache) 470.3 MB (701.4 MB on disk) Reviewed-by: Eric Engestrom <eric.engestrom@intel.com> (v1) Reviewed-by: Eric Anholt <eric@anholt.net>master
# TODO: some of these may be conditional | # TODO: some of these may be conditional | ||||
dep_zlib = dependency('zlib', version : '>= 1.2.3', fallback : ['zlib', 'zlib_dep']) | dep_zlib = dependency('zlib', version : '>= 1.2.3', fallback : ['zlib', 'zlib_dep']) | ||||
pre_args += '-DHAVE_ZLIB' | pre_args += '-DHAVE_ZLIB' | ||||
_zstd = get_option('zstd') | |||||
if _zstd != 'false' | |||||
dep_zstd = dependency('libzstd', required : _zstd == 'true') | |||||
if dep_zstd.found() | |||||
pre_args += '-DHAVE_ZSTD' | |||||
endif | |||||
else | |||||
dep_zstd = null_dep | |||||
endif | |||||
dep_thread = dependency('threads') | dep_thread = dependency('threads') | ||||
if dep_thread.found() and host_machine.system() != 'windows' | if dep_thread.found() and host_machine.system() != 'windows' | ||||
pre_args += '-DHAVE_PTHREAD' | pre_args += '-DHAVE_PTHREAD' |
# Copyright © 2017-2018 Intel Corporation | |||||
# Copyright © 2017-2019 Intel Corporation | |||||
# Permission is hereby granted, free of charge, to any person obtaining a copy | # Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
# of this software and associated documentation files (the "Software"), to deal | # of this software and associated documentation files (the "Software"), to deal | ||||
value : 25, | value : 25, | ||||
description : 'Android Platform SDK version. Default: Nougat version.' | description : 'Android Platform SDK version. Default: Nougat version.' | ||||
) | ) | ||||
option( | |||||
'zstd', | |||||
type : 'combo', | |||||
choices : ['auto', 'true', 'false'], | |||||
value : 'auto', | |||||
description : 'Use ZSTD instead of ZLIB in some cases.' | |||||
) |
#include <inttypes.h> | #include <inttypes.h> | ||||
#include "zlib.h" | #include "zlib.h" | ||||
#ifdef HAVE_ZSTD | |||||
#include "zstd.h" | |||||
#endif | |||||
#include "util/crc32.h" | #include "util/crc32.h" | ||||
#include "util/debug.h" | #include "util/debug.h" | ||||
#include "util/rand_xor.h" | #include "util/rand_xor.h" | ||||
*/ | */ | ||||
#define CACHE_VERSION 1 | #define CACHE_VERSION 1 | ||||
/* 3 is the recomended level, with 22 as the absolute maximum */ | |||||
#define ZSTD_COMPRESSION_LEVEL 3 | |||||
struct disk_cache { | struct disk_cache { | ||||
/* The path to the cache directory. */ | /* The path to the cache directory. */ | ||||
char *path; | char *path; | ||||
deflate_and_write_to_disk(const void *in_data, size_t in_data_size, int dest, | deflate_and_write_to_disk(const void *in_data, size_t in_data_size, int dest, | ||||
const char *filename) | const char *filename) | ||||
{ | { | ||||
#ifdef HAVE_ZSTD | |||||
/* from the zstd docs (https://facebook.github.io/zstd/zstd_manual.html): | |||||
* compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. | |||||
*/ | |||||
size_t out_size = ZSTD_compressBound(in_data_size); | |||||
void * out = malloc(out_size); | |||||
size_t ret = ZSTD_compress(out, out_size, in_data, in_data_size, | |||||
ZSTD_COMPRESSION_LEVEL); | |||||
if (ZSTD_isError(ret)) { | |||||
free(out); | |||||
return 0; | |||||
} | |||||
write_all(dest, out, ret); | |||||
free(out); | |||||
return ret; | |||||
#else | |||||
unsigned char *out; | unsigned char *out; | ||||
/* allocate deflate state */ | /* allocate deflate state */ | ||||
(void)deflateEnd(&strm); | (void)deflateEnd(&strm); | ||||
free(out); | free(out); | ||||
return compressed_size; | return compressed_size; | ||||
# endif | |||||
} | } | ||||
static struct disk_cache_put_job * | static struct disk_cache_put_job * | ||||
inflate_cache_data(uint8_t *in_data, size_t in_data_size, | inflate_cache_data(uint8_t *in_data, size_t in_data_size, | ||||
uint8_t *out_data, size_t out_data_size) | uint8_t *out_data, size_t out_data_size) | ||||
{ | { | ||||
#ifdef HAVE_ZSTD | |||||
size_t ret = ZSTD_decompress(out_data, out_data_size, in_data, in_data_size); | |||||
return !ZSTD_isError(ret); | |||||
#else | |||||
z_stream strm; | z_stream strm; | ||||
/* allocate inflate state */ | /* allocate inflate state */ | ||||
/* clean up and return */ | /* clean up and return */ | ||||
(void)inflateEnd(&strm); | (void)inflateEnd(&strm); | ||||
return true; | return true; | ||||
#endif | |||||
} | } | ||||
void * | void * |
dep_atomic, | dep_atomic, | ||||
dep_m, | dep_m, | ||||
dep_valgrind, | dep_valgrind, | ||||
dep_zstd, | |||||
] | ] | ||||
if with_platform_android | if with_platform_android |