Mark the functions to be optimized
those that shall not be.
This commit is contained in:
1 parent
29fe80a6af
commit
8fd79f07d5
1 file changed
+25
-14
@@ -1513,7 +1513,7 @@ enum m_d1ct_oa_element_e {
|
|||||||
dict->data = NULL; \
|
dict->data = NULL; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
M_INLINE value_type * \
|
M_INLINE value_type * M_ATTR_HOT_FUNCTION \
|
||||||
M_F(name, _get)(const dict_t dict, key_type const key) \
|
M_F(name, _get)(const dict_t dict, key_type const key) \
|
||||||
{ \
|
{ \
|
||||||
M_D1CT_OA_CONTRACT(dict); \
|
M_D1CT_OA_CONTRACT(dict); \
|
||||||
@@ -1555,7 +1555,7 @@ enum m_d1ct_oa_element_e {
|
|||||||
} \
|
} \
|
||||||
) \
|
) \
|
||||||
\
|
\
|
||||||
M_INLINE void \
|
M_INLINE void M_ATTR_COLD_FUNCTION \
|
||||||
M_C3(m_d1ct_,name,_resize_up)(dict_t h, size_t newSize, bool updateLimit) \
|
M_C3(m_d1ct_,name,_resize_up)(dict_t h, size_t newSize, bool updateLimit) \
|
||||||
{ \
|
{ \
|
||||||
size_t oldSize = h->mask+1; \
|
size_t oldSize = h->mask+1; \
|
||||||
@@ -1571,17 +1571,29 @@ enum m_d1ct_oa_element_e {
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* First mark the extended space as empty */ \
|
/* First mark the extended space as empty */ \
|
||||||
for(size_t i = oldSize ; i < newSize; i++) \
|
M_ASSUME( oldSize + 8 < newSize); \
|
||||||
M_CALL_OOR_SET(key_oplist, data[i].key, M_D1CT_OA_EMPTY); \
|
for(size_t i = oldSize ; i < newSize; i+=8) { \
|
||||||
|
/* Unroll loop as compiler doesn't do it by itself */ \
|
||||||
|
M_CALL_OOR_SET(key_oplist, data[i+0].key, M_D1CT_OA_EMPTY); \
|
||||||
|
M_CALL_OOR_SET(key_oplist, data[i+1].key, M_D1CT_OA_EMPTY); \
|
||||||
|
M_CALL_OOR_SET(key_oplist, data[i+2].key, M_D1CT_OA_EMPTY); \
|
||||||
|
M_CALL_OOR_SET(key_oplist, data[i+3].key, M_D1CT_OA_EMPTY); \
|
||||||
|
M_CALL_OOR_SET(key_oplist, data[i+4].key, M_D1CT_OA_EMPTY); \
|
||||||
|
M_CALL_OOR_SET(key_oplist, data[i+5].key, M_D1CT_OA_EMPTY); \
|
||||||
|
M_CALL_OOR_SET(key_oplist, data[i+6].key, M_D1CT_OA_EMPTY); \
|
||||||
|
M_CALL_OOR_SET(key_oplist, data[i+7].key, M_D1CT_OA_EMPTY); \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* Then let's rehash all the entries in their **exact** position. \
|
/* Then let's rehash all the entries in their **exact** position. \
|
||||||
If we can't, let's put them in the 'tmp' array. \
|
If we can't, let's put them in the 'tmp' array. \
|
||||||
It has been measured that the size of this 'tmp' array is \
|
It has been measured that the size of this 'tmp' array is \
|
||||||
around 6% of the size of updated dictionary. \
|
around 6% of the size of updated dictionary. \
|
||||||
NOTE: This should be much cache friendly than typical hash code */ \
|
NOTE: This should be much cache friendly than typical hash code \
|
||||||
|
Reserve a little bit of array to avoid reallocation if possible */ \
|
||||||
M_F(name, _array_pair_ct) tmp; \
|
M_F(name, _array_pair_ct) tmp; \
|
||||||
M_F(name, _array_pair_init)(tmp); \
|
M_F(name, _array_pair_init)(tmp); \
|
||||||
|
M_F(name, _array_pair_reserve)(tmp, oldSize >> 2); \
|
||||||
const size_t mask = (newSize -1); \
|
const size_t mask = (newSize -1); \
|
||||||
\
|
\
|
||||||
for(size_t i = 0 ; i < oldSize; i++) { \
|
for(size_t i = 0 ; i < oldSize; i++) { \
|
||||||
@@ -1611,13 +1623,12 @@ enum m_d1ct_oa_element_e {
|
|||||||
while (M_F(name, _array_pair_size)(tmp) > 0) { \
|
while (M_F(name, _array_pair_size)(tmp) > 0) { \
|
||||||
M_F(name, _pair_ct) const *item = M_F(name, _array_pair_back)(tmp); \
|
M_F(name, _pair_ct) const *item = M_F(name, _array_pair_back)(tmp); \
|
||||||
size_t p = M_CALL_HASH(key_oplist, item->key) & mask; \
|
size_t p = M_CALL_HASH(key_oplist, item->key) & mask; \
|
||||||
|
size_t s = 1; \
|
||||||
/* NOTE: since the first pass, the bucket might be free now */ \
|
/* NOTE: since the first pass, the bucket might be free now */ \
|
||||||
if (!M_CALL_OOR_EQUAL(key_oplist, data[p].key, M_D1CT_OA_EMPTY)) { \
|
/* Likely cache miss */ \
|
||||||
size_t s = 1; \
|
while (!M_CALL_OOR_EQUAL(key_oplist, data[p].key, M_D1CT_OA_EMPTY)) { \
|
||||||
do { \
|
p = (p + M_D1CT_OA_PROBING(s)) & mask; \
|
||||||
p = (p + M_D1CT_OA_PROBING(s)) & mask; \
|
M_ASSERT (s <= h->mask); \
|
||||||
M_ASSERT (s <= h->mask); \
|
|
||||||
} while (!M_CALL_OOR_EQUAL(key_oplist, data[p].key, M_D1CT_OA_EMPTY) ); \
|
|
||||||
} \
|
} \
|
||||||
M_F(name, _array_pair_pop_move)(&data[p], tmp); \
|
M_F(name, _array_pair_pop_move)(&data[p], tmp); \
|
||||||
} \
|
} \
|
||||||
@@ -1633,7 +1644,7 @@ enum m_d1ct_oa_element_e {
|
|||||||
M_D1CT_OA_CONTRACT(h); \
|
M_D1CT_OA_CONTRACT(h); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
M_INLINE void \
|
M_INLINE void M_ATTR_HOT_FUNCTION \
|
||||||
M_IF(isSet)(M_F(name, _push), M_F(name,_set_at)) \
|
M_IF(isSet)(M_F(name, _push), M_F(name,_set_at)) \
|
||||||
(dict_t dict, key_type const key \
|
(dict_t dict, key_type const key \
|
||||||
M_IF(isSet)(, M_DEFERRED_COMMA value_type const value) ) \
|
M_IF(isSet)(, M_DEFERRED_COMMA value_type const value) ) \
|
||||||
@@ -1693,7 +1704,7 @@ enum m_d1ct_oa_element_e {
|
|||||||
M_D1CT_OA_CONTRACT(dict); \
|
M_D1CT_OA_CONTRACT(dict); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
M_INLINE value_type * \
|
M_INLINE value_type * M_ATTR_HOT_FUNCTION \
|
||||||
M_F(name,_safe_get)(dict_t dict, key_type const key) \
|
M_F(name,_safe_get)(dict_t dict, key_type const key) \
|
||||||
{ \
|
{ \
|
||||||
M_D1CT_OA_CONTRACT(dict); \
|
M_D1CT_OA_CONTRACT(dict); \
|
||||||
@@ -1755,7 +1766,7 @@ enum m_d1ct_oa_element_e {
|
|||||||
return M_F(name,_safe_get)(dict, key); \
|
return M_F(name,_safe_get)(dict, key); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
M_INLINE void \
|
M_INLINE void M_ATTR_COLD_FUNCTION \
|
||||||
M_C3(m_d1ct_,name,_resize_down)(dict_t h, size_t newSize) \
|
M_C3(m_d1ct_,name,_resize_down)(dict_t h, size_t newSize) \
|
||||||
{ \
|
{ \
|
||||||
size_t oldSize = h->mask+1; \
|
size_t oldSize = h->mask+1; \
|
||||||
|
|||||||
Reference in new issue
Block a user