eo - eo ptr lookup - do some prefetches to get some micro-speedups

prefetching a bit helps.. a bit like 0.2% or so... but it does help. :)
This commit is contained in:
Carsten Haitzler 2016-10-01 23:37:34 +09:00
parent a2d507d3bf
commit 7b3e7ecc1f
2 changed files with 32 additions and 28 deletions

View File

@ -66,7 +66,6 @@ _eo_obj_pointer_get(const Eo_Id obj_id)
{ {
#ifdef HAVE_EO_ID #ifdef HAVE_EO_ID
_Eo_Id_Entry *entry; _Eo_Id_Entry *entry;
_Eo_Object *ptr;
Generation_Counter generation; Generation_Counter generation;
Table_Index mid_table_id, table_id, entry_id; Table_Index mid_table_id, table_id, entry_id;
Eo_Id tag_bit; Eo_Id tag_bit;
@ -77,27 +76,30 @@ _eo_obj_pointer_get(const Eo_Id obj_id)
// NULL objects will just be sensibly ignored. not worth complaining // NULL objects will just be sensibly ignored. not worth complaining
// every single time. // every single time.
domain = (obj_id >> SHIFT_DOMAIN) & MASK_DOMAIN;
data = _eo_table_data_get(); data = _eo_table_data_get();
EINA_PREFETCH(&(data->tables[0]));
domain = (obj_id >> SHIFT_DOMAIN) & MASK_DOMAIN;
tdata = _eo_table_data_table_get(data, domain); tdata = _eo_table_data_table_get(data, domain);
if (!tdata) goto err; EINA_PREFETCH(&(tdata->cache.id));
if (EINA_UNLIKELY(!tdata)) goto err;
if (EINA_LIKELY(domain != EFL_ID_DOMAIN_SHARED)) if (EINA_LIKELY(domain != EFL_ID_DOMAIN_SHARED))
{ {
if (obj_id == tdata->cache.id) if (obj_id == tdata->cache.id)
{ return tdata->cache.object;
ptr = tdata->cache.object;
return ptr; mid_table_id = (obj_id >> SHIFT_MID_TABLE_ID) & MASK_MID_TABLE_ID;
} EINA_PREFETCH(&(tdata->eo_ids_tables[mid_table_id]));
table_id = (obj_id >> SHIFT_TABLE_ID) & MASK_TABLE_ID;
entry_id = (obj_id >> SHIFT_ENTRY_ID) & MASK_ENTRY_ID;
generation = obj_id & MASK_GENERATIONS;
// get tag bit to check later down below - pipelining // get tag bit to check later down below - pipelining
tag_bit = (obj_id) & MASK_OBJ_TAG; tag_bit = (obj_id) & MASK_OBJ_TAG;
if (!obj_id) goto err_null; if (!obj_id) goto err_null;
else if (!tag_bit) goto err; else if (!tag_bit) goto err;
EO_DECOMPOSE_ID(obj_id, mid_table_id, table_id, entry_id, generation);
// Check the validity of the entry // Check the validity of the entry
if (tdata->eo_ids_tables[mid_table_id]) if (tdata->eo_ids_tables[mid_table_id])
{ {
@ -111,8 +113,7 @@ _eo_obj_pointer_get(const Eo_Id obj_id)
// Cache the result of that lookup // Cache the result of that lookup
tdata->cache.object = entry->ptr; tdata->cache.object = entry->ptr;
tdata->cache.id = obj_id; tdata->cache.id = obj_id;
ptr = entry->ptr; return entry->ptr;
return ptr;
} }
} }
} }
@ -122,18 +123,22 @@ _eo_obj_pointer_get(const Eo_Id obj_id)
{ {
eina_lock_take(&(_eo_table_data_shared_data->obj_lock)); eina_lock_take(&(_eo_table_data_shared_data->obj_lock));
if (obj_id == tdata->cache.id) if (obj_id == tdata->cache.id)
{ // yes we return keeping the lock locked. thats why
ptr = tdata->cache.object; // you must call _eo_obj_pointer_done() wrapped
return ptr; // by EO_OBJ_DONE() to release
} return tdata->cache.object;
mid_table_id = (obj_id >> SHIFT_MID_TABLE_ID) & MASK_MID_TABLE_ID;
EINA_PREFETCH(&(tdata->eo_ids_tables[mid_table_id]));
table_id = (obj_id >> SHIFT_TABLE_ID) & MASK_TABLE_ID;
entry_id = (obj_id >> SHIFT_ENTRY_ID) & MASK_ENTRY_ID;
generation = obj_id & MASK_GENERATIONS;
// get tag bit to check later down below - pipelining // get tag bit to check later down below - pipelining
tag_bit = (obj_id) & MASK_OBJ_TAG; tag_bit = (obj_id) & MASK_OBJ_TAG;
if (!obj_id) goto err_shared_null; if (!obj_id) goto err_shared_null;
else if (!tag_bit) goto err_shared; else if (!tag_bit) goto err_shared;
EO_DECOMPOSE_ID(obj_id, mid_table_id, table_id, entry_id, generation);
// Check the validity of the entry // Check the validity of the entry
if (tdata->eo_ids_tables[mid_table_id]) if (tdata->eo_ids_tables[mid_table_id])
{ {
@ -147,11 +152,10 @@ _eo_obj_pointer_get(const Eo_Id obj_id)
// Cache the result of that lookup // Cache the result of that lookup
tdata->cache.object = entry->ptr; tdata->cache.object = entry->ptr;
tdata->cache.id = obj_id; tdata->cache.id = obj_id;
ptr = entry->ptr;
// yes we return keeping the lock locked. thats why // yes we return keeping the lock locked. thats why
// you must call _eo_obj_pointer_done() wrapped // you must call _eo_obj_pointer_done() wrapped
// by EO_OBJ_DONE() to release // by EO_OBJ_DONE() to release
return ptr; return entry->ptr;
} }
} }
} }

View File

@ -251,12 +251,6 @@ typedef struct _Eo_Id_Table_Data Eo_Id_Table_Data;
struct _Eo_Id_Table_Data struct _Eo_Id_Table_Data
{ {
/* Tables handling pointers indirection */
_Eo_Ids_Table **eo_ids_tables[MAX_MID_TABLE_ID];
/* Current table used for following allocations */
_Eo_Ids_Table *current_table;
/* Spare empty table */
_Eo_Ids_Table *empty_table;
/* Cached eoid lookups */ /* Cached eoid lookups */
struct struct
{ {
@ -267,12 +261,18 @@ struct _Eo_Id_Table_Data
Eina_Bool isa; Eina_Bool isa;
} }
cache; cache;
/* Next generation to use when assigning a new entry to a Eo pointer */ /* Tables handling pointers indirection */
Generation_Counter generation; _Eo_Ids_Table **eo_ids_tables[MAX_MID_TABLE_ID];
/* Current table used for following allocations */
_Eo_Ids_Table *current_table;
/* Spare empty table */
_Eo_Ids_Table *empty_table;
/* Optional lock around all objects in eoid table - only used if shared */ /* Optional lock around all objects in eoid table - only used if shared */
Eina_Lock obj_lock; Eina_Lock obj_lock;
/* Next generation to use when assigning a new entry to a Eo pointer */
Generation_Counter generation;
/* are we shared so we need lock/unlock? */ /* are we shared so we need lock/unlock? */
Eina_Bool shared : 1; Eina_Bool shared;
}; };
struct _Eo_Id_Data struct _Eo_Id_Data