main sync #3

Merged
Patrick Busch merged 318 commits from blender/blender:main into main 2023-03-17 15:52:21 +01:00
Showing only changes of commit 7a5cb3b470 - Show all commits

View File

@ -142,13 +142,30 @@
#ifdef USE_HASH_TABLE_ACCUMULATE #ifdef USE_HASH_TABLE_ACCUMULATE
/* Number of times to propagate hashes back. /* Number of times to propagate hashes back.
* Effectively a 'triangle-number'. * Effectively a 'triangle-number'.
* so 4 -> 7, 5 -> 10, 6 -> 15... etc. * so 3 -> 7, 4 -> 11, 5 -> 16, 6 -> 22, 7 -> 29, ... etc.
*
* \note additional steps are expensive, so avoid high values unless necessary
* (with low strides, between 1-4) where a low value would cause the hashes to
* be un-evenly distributed.
*/ */
# define BCHUNK_HASH_TABLE_ACCUMULATE_STEPS 4 # define BCHUNK_HASH_TABLE_ACCUMULATE_STEPS_DEFAULT 3
# define BCHUNK_HASH_TABLE_ACCUMULATE_STEPS_32BITS 4
# define BCHUNK_HASH_TABLE_ACCUMULATE_STEPS_16BITS 5
/**
* Singe bytes (or boolean) arrays need a higher number of steps
* because the resulting values are not unique enough to result in evenly distributed values.
* Use more accumulation when the the size of the structs is small, see: #105046.
*
* With 6 -> 22, one byte each - means an array of booleans can be combine into 22 bits
* representing 4,194,303 different combinations.
*/
# define BCHUNK_HASH_TABLE_ACCUMULATE_STEPS_8BITS 6
#else #else
/* How many items to hash (multiplied by stride) /**
* How many items to hash (multiplied by stride).
* The more values, the greater the chance this block has a unique hash.
*/ */
# define BCHUNK_HASH_LEN 4 # define BCHUNK_HASH_LEN 16
#endif #endif
/** /**
@ -216,7 +233,10 @@ typedef struct BArrayInfo {
/* min/max limits (inclusive) */ /* min/max limits (inclusive) */
size_t chunk_byte_size_min; size_t chunk_byte_size_min;
size_t chunk_byte_size_max; size_t chunk_byte_size_max;
/**
* The read-ahead value should never exceed `chunk_byte_size`,
* otherwise the hash would be based on values in the next chunk.
*/
size_t accum_read_ahead_bytes; size_t accum_read_ahead_bytes;
#ifdef USE_HASH_TABLE_ACCUMULATE #ifdef USE_HASH_TABLE_ACCUMULATE
size_t accum_steps; size_t accum_steps;
@ -943,9 +963,9 @@ static const BChunkRef *table_lookup(const BArrayInfo *info,
static hash_key key_from_chunk_ref(const BArrayInfo *info, const BChunkRef *cref) static hash_key key_from_chunk_ref(const BArrayInfo *info, const BChunkRef *cref)
{ {
const size_t data_hash_len = BCHUNK_HASH_LEN * info->chunk_stride;
hash_key key; hash_key key;
BChunk *chunk = cref->link; BChunk *chunk = cref->link;
const size_t data_hash_len = MIN2(chunk->data_len, BCHUNK_HASH_LEN * info->chunk_stride);
# ifdef USE_HASH_TABLE_KEY_CACHE # ifdef USE_HASH_TABLE_KEY_CACHE
key = chunk->key; key = chunk->key;
@ -1398,6 +1418,8 @@ static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info,
BArrayStore *BLI_array_store_create(uint stride, uint chunk_count) BArrayStore *BLI_array_store_create(uint stride, uint chunk_count)
{ {
BLI_assert(stride > 0 && chunk_count > 0);
BArrayStore *bs = MEM_callocN(sizeof(BArrayStore), __func__); BArrayStore *bs = MEM_callocN(sizeof(BArrayStore), __func__);
bs->info.chunk_stride = stride; bs->info.chunk_stride = stride;
@ -1410,14 +1432,32 @@ BArrayStore *BLI_array_store_create(uint stride, uint chunk_count)
#endif #endif
#ifdef USE_HASH_TABLE_ACCUMULATE #ifdef USE_HASH_TABLE_ACCUMULATE
bs->info.accum_steps = BCHUNK_HASH_TABLE_ACCUMULATE_STEPS - 1; /* One is always subtracted from this `accum_steps`, this is intentional
* as it results in reading ahead the expected amount. */
if (stride <= sizeof(int8_t)) {
bs->info.accum_steps = BCHUNK_HASH_TABLE_ACCUMULATE_STEPS_8BITS + 1;
}
else if (stride <= sizeof(int16_t)) {
bs->info.accum_steps = BCHUNK_HASH_TABLE_ACCUMULATE_STEPS_16BITS + 1;
}
else if (stride <= sizeof(int32_t)) {
bs->info.accum_steps = BCHUNK_HASH_TABLE_ACCUMULATE_STEPS_32BITS + 1;
}
else {
bs->info.accum_steps = BCHUNK_HASH_TABLE_ACCUMULATE_STEPS_DEFAULT + 1;
}
do {
bs->info.accum_steps -= 1;
/* Triangle number, identifying now much read-ahead we need: /* Triangle number, identifying now much read-ahead we need:
* https://en.wikipedia.org/wiki/Triangular_number (+ 1) */ * https://en.wikipedia.org/wiki/Triangular_number (+ 1) */
bs->info.accum_read_ahead_len = bs->info.accum_read_ahead_len = ((bs->info.accum_steps * (bs->info.accum_steps + 1)) / 2) + 1;
(uint)(((bs->info.accum_steps * (bs->info.accum_steps + 1)) / 2) + 1); /* Only small chunk counts are likely to exceed the read-ahead length. */
} while (UNLIKELY(chunk_count < bs->info.accum_read_ahead_len));
bs->info.accum_read_ahead_bytes = bs->info.accum_read_ahead_len * stride; bs->info.accum_read_ahead_bytes = bs->info.accum_read_ahead_len * stride;
#else #else
bs->info.accum_read_ahead_bytes = BCHUNK_HASH_LEN * stride; bs->info.accum_read_ahead_bytes = MIN2((size_t)BCHUNK_HASH_LEN, chunk_count) * stride;
#endif #endif
bs->memory.chunk_list = BLI_mempool_create(sizeof(BChunkList), 0, 512, BLI_MEMPOOL_NOP); bs->memory.chunk_list = BLI_mempool_create(sizeof(BChunkList), 0, 512, BLI_MEMPOOL_NOP);
@ -1426,6 +1466,8 @@ BArrayStore *BLI_array_store_create(uint stride, uint chunk_count)
* (we could loop over all states as an alternative). */ * (we could loop over all states as an alternative). */
bs->memory.chunk = BLI_mempool_create(sizeof(BChunk), 0, 512, BLI_MEMPOOL_ALLOW_ITER); bs->memory.chunk = BLI_mempool_create(sizeof(BChunk), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
BLI_assert(bs->info.accum_read_ahead_bytes <= bs->info.chunk_byte_size);
return bs; return bs;
} }