maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #06823
Re: [svoj@xxxxxxxxxxx: [Commits] Rev 4006: MDEV-5674 - Performance: my_hash_sort_bin is called too often in lp:maria/10.0]
Hi!
The second patch should be on it's way to commits. Also I wrote a blog about it:
http://svoj-db.blogspot.ru/2014/02/mariadb-100-performance-myhashsortbin.html
Regards,
Sergey
On Fri, Feb 14, 2014 at 04:30:29PM +0400, Sergey Vojtovich wrote:
> Hi!
>
> JFYI: we discussed this during the Barcelona meeting. I will submit table cache
> part separately (not to overcomplicate this patch). Reviewers are very welcome.
>
> Regards,
> Sergey
>
>
> ----- Forwarded message from Sergey Vojtovich <svoj@xxxxxxxxxxx> -----
>
> Date: Fri, 14 Feb 2014 12:25:50 +0000 (UTC)
> From: Sergey Vojtovich <svoj@xxxxxxxxxxx>
> To: commits@xxxxxxxxxxx
> Subject: [Commits] Rev 4006: MDEV-5674 - Performance: my_hash_sort_bin is called too often in lp:maria/10.0
>
> At lp:maria/10.0
>
> ------------------------------------------------------------
> revno: 4006
> revision-id: svoj@xxxxxxxxxxx-20140214122541-tenvcllk760deai8
> parent: svoj@xxxxxxxxxxx-20140213071355-psk0jpsarx2u7myc
> committer: Sergey Vojtovich <svoj@xxxxxxxxxxx>
> branch nick: 10.0
> timestamp: Fri 2014-02-14 16:25:41 +0400
> message:
> MDEV-5674 - Performance: my_hash_sort_bin is called too often
>
> - reduced number of my_hash_sort_bin() calls from 4 to 2 per query.
> Let MDL subsystem use pre-calculated hash value for hash
> inserts and deletes.
> - reduced number of memory accesses done by my_hash_sort_bin()
> === modified file 'include/hash.h'
> --- a/include/hash.h 2013-09-14 01:09:36 +0000
> +++ b/include/hash.h 2014-02-14 12:25:41 +0000
> @@ -86,7 +86,13 @@ uchar *my_hash_first_from_hash_value(con
> uchar *my_hash_next(const HASH *info, const uchar *key, size_t length,
> HASH_SEARCH_STATE *state);
> my_bool my_hash_insert(HASH *info, const uchar *data);
> +my_bool my_hash_insert_using_hash_value(HASH *info,
> + my_hash_value_type hash_value,
> + const uchar *record);
> my_bool my_hash_delete(HASH *hash, uchar *record);
> +my_bool my_hash_delete_using_hash_value(HASH *hash,
> + my_hash_value_type hash_value,
> + uchar *record);
> my_bool my_hash_update(HASH *hash, uchar *record, uchar *old_key,
> size_t old_key_length);
> void my_hash_replace(HASH *hash, HASH_SEARCH_STATE *state, uchar *new_row);
>
> === modified file 'mysys/hash.c'
> --- a/mysys/hash.c 2013-09-14 01:09:36 +0000
> +++ b/mysys/hash.c 2014-02-14 12:25:41 +0000
> @@ -380,6 +380,15 @@ static int hashcmp(const HASH *hash, HAS
>
> my_bool my_hash_insert(HASH *info, const uchar *record)
> {
> + return my_hash_insert_using_hash_value(info, rec_hashnr(info, record),
> + record);
> +}
> +
> +
> +my_bool my_hash_insert_using_hash_value(HASH *info,
> + my_hash_value_type hash_value,
> + const uchar *record)
> +{
> int flag;
> size_t idx,halfbuff,first_index;
> my_hash_value_type hash_nr;
> @@ -480,7 +489,7 @@ my_bool my_hash_insert(HASH *info, const
> }
> /* Check if we are at the empty position */
>
> - idx= my_hash_mask(rec_hashnr(info, record), info->blength, info->records + 1);
> + idx= my_hash_mask(hash_value, info->blength, info->records + 1);
> pos=data+idx;
> if (pos == empty)
> {
> @@ -528,6 +537,15 @@ my_bool my_hash_insert(HASH *info, const
>
> my_bool my_hash_delete(HASH *hash, uchar *record)
> {
> + return my_hash_delete_using_hash_value(hash, rec_hashnr(hash, record),
> + record);
> +}
> +
> +
> +my_bool my_hash_delete_using_hash_value(HASH *hash,
> + my_hash_value_type hash_value,
> + uchar *record)
> +{
> uint pos2,idx,empty_index;
> my_hash_value_type pos_hashnr, lastpos_hashnr;
> size_t blength;
> @@ -539,7 +557,7 @@ my_bool my_hash_delete(HASH *hash, uchar
> blength=hash->blength;
> data=dynamic_element(&hash->array,0,HASH_LINK*);
> /* Search after record with key */
> - pos= data + my_hash_mask(rec_hashnr(hash, record), blength, hash->records);
> + pos= data + my_hash_mask(hash_value, blength, hash->records);
> gpos = 0;
>
> while (pos->data != record)
>
> === modified file 'sql/mdl.cc'
> --- a/sql/mdl.cc 2013-12-10 15:31:04 +0000
> +++ b/sql/mdl.cc 2014-02-14 12:25:41 +0000
> @@ -124,15 +124,9 @@ class MDL_map_partition
> public:
> MDL_map_partition();
> ~MDL_map_partition();
> - inline MDL_lock *find_or_insert(const MDL_key *mdl_key,
> - my_hash_value_type hash_value);
> - unsigned long get_lock_owner(const MDL_key *key,
> - my_hash_value_type hash_value);
> + inline MDL_lock *find_or_insert(const MDL_key *mdl_key);
> + unsigned long get_lock_owner(const MDL_key *key);
> inline void remove(MDL_lock *lock);
> - my_hash_value_type get_key_hash(const MDL_key *mdl_key) const
> - {
> - return my_calc_hash(&m_locks, mdl_key->ptr(), mdl_key->length());
> - }
> private:
> bool move_from_hash_to_lock_mutex(MDL_lock *lock);
> /** A partition of all acquired locks in the server. */
> @@ -846,11 +840,10 @@ MDL_lock* MDL_map::find_or_insert(const
> return lock;
> }
>
> - my_hash_value_type hash_value= m_partitions.at(0)->get_key_hash(mdl_key);
> - uint part_id= hash_value % mdl_locks_hash_partitions;
> + uint part_id= mdl_key->hash_value() % mdl_locks_hash_partitions;
> MDL_map_partition *part= m_partitions.at(part_id);
>
> - return part->find_or_insert(mdl_key, hash_value);
> + return part->find_or_insert(mdl_key);
> }
>
>
> @@ -863,15 +856,14 @@ MDL_lock* MDL_map::find_or_insert(const
> @retval NULL - Failure (OOM).
> */
>
> -MDL_lock* MDL_map_partition::find_or_insert(const MDL_key *mdl_key,
> - my_hash_value_type hash_value)
> +MDL_lock* MDL_map_partition::find_or_insert(const MDL_key *mdl_key)
> {
> MDL_lock *lock;
>
> retry:
> mysql_mutex_lock(&m_mutex);
> if (!(lock= (MDL_lock*) my_hash_search_using_hash_value(&m_locks,
> - hash_value,
> + mdl_key->hash_value(),
> mdl_key->ptr(),
> mdl_key->length())))
> {
> @@ -902,7 +894,9 @@ MDL_lock* MDL_map_partition::find_or_ins
> lock= MDL_lock::create(mdl_key, this);
> }
>
> - if (!lock || my_hash_insert(&m_locks, (uchar*)lock))
> + if (!lock || my_hash_insert_using_hash_value(&m_locks,
> + mdl_key->hash_value(),
> + (uchar*) lock))
> {
> if (unused_lock)
> {
> @@ -1023,10 +1017,9 @@ MDL_map::get_lock_owner(const MDL_key *m
> }
> else
> {
> - my_hash_value_type hash_value= m_partitions.at(0)->get_key_hash(mdl_key);
> - uint part_id= hash_value % mdl_locks_hash_partitions;
> + uint part_id= mdl_key->hash_value() % mdl_locks_hash_partitions;
> MDL_map_partition *part= m_partitions.at(part_id);
> - res= part->get_lock_owner(mdl_key, hash_value);
> + res= part->get_lock_owner(mdl_key);
> }
> return res;
> }
> @@ -1034,15 +1027,14 @@ MDL_map::get_lock_owner(const MDL_key *m
>
>
> unsigned long
> -MDL_map_partition::get_lock_owner(const MDL_key *mdl_key,
> - my_hash_value_type hash_value)
> +MDL_map_partition::get_lock_owner(const MDL_key *mdl_key)
> {
> MDL_lock *lock;
> unsigned long res= 0;
>
> mysql_mutex_lock(&m_mutex);
> lock= (MDL_lock*) my_hash_search_using_hash_value(&m_locks,
> - hash_value,
> + mdl_key->hash_value(),
> mdl_key->ptr(),
> mdl_key->length());
> if (lock)
> @@ -1085,7 +1077,8 @@ void MDL_map::remove(MDL_lock *lock)
> void MDL_map_partition::remove(MDL_lock *lock)
> {
> mysql_mutex_lock(&m_mutex);
> - my_hash_delete(&m_locks, (uchar*) lock);
> + my_hash_delete_using_hash_value(&m_locks, lock->key.hash_value(),
> + (uchar*) lock);
> /*
> To let threads holding references to the MDL_lock object know that it was
> moved to the list of unused objects or destroyed, we increment the version
>
> === modified file 'sql/mdl.h'
> --- a/sql/mdl.h 2013-12-16 08:26:20 +0000
> +++ b/sql/mdl.h 2014-02-14 12:25:41 +0000
> @@ -347,12 +347,17 @@ class MDL_key
> m_ptr - 1);
> m_length= static_cast<uint16>(strmake(m_ptr + m_db_name_length + 2, name,
> NAME_LEN) - m_ptr + 1);
> + ulong nr2= 4;
> + m_hash_value= 1;
> + my_charset_bin.coll->hash_sort(&my_charset_bin, (uchar*) m_ptr, m_length,
> + &m_hash_value, &nr2);
> }
> void mdl_key_init(const MDL_key *rhs)
> {
> memcpy(m_ptr, rhs->m_ptr, rhs->m_length);
> m_length= rhs->m_length;
> m_db_name_length= rhs->m_db_name_length;
> + m_hash_value= rhs->m_hash_value;
> }
> bool is_equal(const MDL_key *rhs) const
> {
> @@ -392,10 +397,15 @@ class MDL_key
> {
> return & m_namespace_to_wait_state_name[(int)mdl_namespace()];
> }
> + ulong hash_value() const
> + {
> + return m_hash_value;
> + }
>
> private:
> uint16 m_length;
> uint16 m_db_name_length;
> + ulong m_hash_value;
> char m_ptr[MAX_MDLKEY_LENGTH];
> static PSI_stage_info m_namespace_to_wait_state_name[NAMESPACE_END];
> private:
>
> === modified file 'strings/ctype-bin.c'
> --- a/strings/ctype-bin.c 2013-11-20 11:05:39 +0000
> +++ b/strings/ctype-bin.c 2014-02-14 12:25:41 +0000
> @@ -277,7 +277,9 @@ void my_hash_sort_8bit_bin(CHARSET_INFO
> ulong *nr1, ulong *nr2)
> {
> const uchar *pos = key;
> -
> + ulong tmp1= *nr1;
> + ulong tmp2= *nr2;
> +
> /*
> Remove trailing spaces. We have to do this to be able to compare
> 'A ' and 'A' as identical
> @@ -286,10 +288,13 @@ void my_hash_sort_8bit_bin(CHARSET_INFO
>
> for (; pos < (uchar*) key ; pos++)
> {
> - nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
> - ((uint)*pos)) + (nr1[0] << 8);
> - nr2[0]+=3;
> + tmp1^= (ulong) ((((uint) tmp1 & 63) + tmp2) *
> + ((uint) *pos)) + (tmp1 << 8);
> + tmp2+= 3;
> }
> +
> + *nr1= tmp1;
> + *nr2= tmp2;
> }
>
>
> @@ -297,15 +302,20 @@ void my_hash_sort_bin(CHARSET_INFO *cs _
> const uchar *key, size_t len,ulong *nr1, ulong *nr2)
> {
> const uchar *pos = key;
> -
> + ulong tmp1= *nr1;
> + ulong tmp2= *nr2;
> +
> key+= len;
> -
> +
> for (; pos < (uchar*) key ; pos++)
> {
> - nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
> - ((uint)*pos)) + (nr1[0] << 8);
> - nr2[0]+=3;
> + tmp1^= (ulong) ((((uint) tmp1 & 63) + tmp2) *
> + ((uint) *pos)) + (tmp1 << 8);
> + tmp2+= 3;
> }
> +
> + *nr1= tmp1;
> + *nr2= tmp2;
> }
>
>
>
> _______________________________________________
> commits mailing list
> commits@xxxxxxxxxxx
> https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
>
> ----- End forwarded message -----
>
> _______________________________________________
> Mailing list: https://launchpad.net/~maria-developers
> Post to : maria-developers@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~maria-developers
> More help : https://help.launchpad.net/ListHelp
References