Skip to content

Commit aa60561

Browse files
committed
Blah
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags:
1 parent f07fbc5 commit aa60561

File tree

2 files changed

+88
-8
lines changed

2 files changed

+88
-8
lines changed

Include/internal/pycore_typeobject.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ struct type_cache {
7676
// Type attribute lookup cache which is type-specific. Only used
7777
// for heap types where we store a small additional cache in free-threaded
7878
// builds which can be accessed without any locking.
79-
#define LOCAL_TYPE_CACHE_SIZE 32
80-
#define LOCAL_TYPE_CACHE_MAX_ENTRIES 24
81-
#define LOCAL_TYPE_CACHE_PROBE 3
79+
#define LOCAL_TYPE_CACHE_SIZE 64
80+
#define LOCAL_TYPE_CACHE_MAX_ENTRIES 48
81+
#define LOCAL_TYPE_CACHE_PROBE 7
8282

8383
struct local_type_cache_entry {
8484
PyObject *name; // reference to exactly a str or NULL
@@ -89,6 +89,9 @@ struct local_type_cache {
8989
unsigned int tp_version_tag;
9090
unsigned int cache_count;
9191
struct local_type_cache_entry entries[LOCAL_TYPE_CACHE_SIZE];
92+
#if 0
93+
int hits[LOCAL_TYPE_CACHE_SIZE], probes[LOCAL_TYPE_CACHE_SIZE], miss[LOCAL_TYPE_CACHE_SIZE];
94+
#endif
9295
};
9396

9497
#endif

Objects/typeobject.c

+82-5
Original file line numberDiff line numberDiff line change
@@ -5625,9 +5625,9 @@ get_local_type_cache(PyTypeObject *type, unsigned int assigned_version)
56255625
return NULL;
56265626
}
56275627

5628-
#define HASH_NAME(name) (((Py_ssize_t)(name)) >> 6)
5628+
#define HASH_NAME(name) ((((Py_ssize_t)(name)) >> 6) % LOCAL_TYPE_CACHE_SIZE)
56295629

5630-
static bool
5630+
static inline bool
56315631
try_local_cache_lookup(PyTypeObject *type, PyObject *name, PyObject **value, unsigned int *version)
56325632
{
56335633
if (!can_cache_locally(type, name)) {
@@ -5639,9 +5639,15 @@ try_local_cache_lookup(PyTypeObject *type, PyObject *name, PyObject **value, uns
56395639
return false;
56405640
}
56415641

5642-
Py_ssize_t index = HASH_NAME(name) % LOCAL_TYPE_CACHE_SIZE;
5642+
Py_ssize_t index = HASH_NAME(name);
56435643
Py_ssize_t cur = index;
5644+
#if 0
5645+
static int probe, count;
5646+
#endif
56445647
do {
5648+
#if 0
5649+
local_cache->probes[cur]++;
5650+
#endif
56455651
struct local_type_cache_entry *entry = &local_cache->entries[cur];
56465652
PyObject *entry_name = _Py_atomic_load_ptr_acquire(&entry->name);
56475653
if (entry_name == name) {
@@ -5656,18 +5662,89 @@ try_local_cache_lookup(PyTypeObject *type, PyObject *name, PyObject **value, uns
56565662
if (version) {
56575663
*version = local_cache->tp_version_tag;
56585664
}
5665+
5666+
#if 0
5667+
if(hits[cur] - probes[cur] < -50000) {
5668+
count ++;
5669+
if(count < 50) {
5670+
printf("misfire: %s %s(%p) %ld %s(%p) %ld %d\n",
5671+
type->tp_name,
5672+
5673+
PyUnicode_AsUTF8(name),
5674+
name,
5675+
cur,
5676+
5677+
PyUnicode_AsUTF8(local_cache->entries[index].name),
5678+
local_cache->entries[index].name,
5679+
index,
5680+
5681+
local_cache->cache_count);
5682+
5683+
static int foo[LOCAL_TYPE_CACHE_SIZE + 1];
5684+
for(int j = 2; j<LOCAL_TYPE_CACHE_SIZE + 1; j++) {
5685+
for(int i = 0; i<LOCAL_TYPE_CACHE_SIZE + 1; i++) {
5686+
foo[i] = 0;
5687+
}
5688+
for(int i = 0; i<LOCAL_TYPE_CACHE_SIZE; i++) {
5689+
PyObject *name = local_cache->entries[i].name;
5690+
if (name != NULL) {
5691+
Py_ssize_t idx = ((Py_ssize_t)(name)) % j;
5692+
foo[idx] += 1;
5693+
if(name != NULL) {
5694+
//printf("%d %s %p\n", i, PyUnicode_AsUTF8(name), name);
5695+
}
5696+
}
5697+
}
5698+
int collisions = 0;
5699+
for(int i = 0; i<LOCAL_TYPE_CACHE_SIZE + 1; i++) {
5700+
if(foo[i] > 1) {
5701+
collisions += foo[i];
5702+
}
5703+
}
5704+
printf("Good match at %d %d\n", j, collisions);
5705+
}
5706+
}
5707+
}
5708+
#endif
5709+
5710+
#if 0
5711+
local_cache->hits[cur]++;
5712+
static int hit_count;
5713+
hit_count++;
5714+
5715+
if((hit_count % 500000) == 0) {
5716+
printf("Avg %d %d\n", hit_count/LOCAL_TYPE_CACHE_SIZE, probe);
5717+
for(int i = 0 ;i<LOCAL_TYPE_CACHE_SIZE; i++) {
5718+
PyObject *name = local_cache->entries[i].name;
5719+
printf("%02x hits: %6d probes: %6d delta: %6d missed: %d %p %s %lx\n",
5720+
i,
5721+
local_cache->hits[i],
5722+
local_cache->probes[i], local_cache->probes[i] - local_cache->hits[i], local_cache->miss[i],
5723+
name,
5724+
name != NULL ? PyUnicode_AsUTF8(name) : "<NULL>",
5725+
name != NULL ? (HASH_NAME(name) % LOCAL_TYPE_CACHE_SIZE) : 0);
5726+
}
5727+
}
5728+
#endif
56595729

56605730
return true;
56615731
}
56625732
else if (entry_name == NULL) {
56635733
break;
56645734
}
5735+
#if 0
5736+
probe++;
5737+
#endif
56655738
cur = (cur + LOCAL_TYPE_CACHE_PROBE) % LOCAL_TYPE_CACHE_SIZE;
56665739
} while (cur != index);
5740+
#if 0
5741+
local_cache->miss[index]++;
5742+
#endif
56675743
return false;
56685744
}
56695745

5670-
static bool
5746+
5747+
static inline bool
56715748
cache_local_type_lookup(PyTypeObject *type, PyObject *name,
56725749
PyObject *res, unsigned int assigned_version)
56735750
{
@@ -5682,7 +5759,7 @@ cache_local_type_lookup(PyTypeObject *type, PyObject *name,
56825759
return false;
56835760
}
56845761

5685-
Py_ssize_t index = HASH_NAME(name) % LOCAL_TYPE_CACHE_SIZE;
5762+
Py_ssize_t index = HASH_NAME(name);
56865763
Py_ssize_t cur = index;
56875764
do {
56885765
struct local_type_cache_entry *entry = &local_cache->entries[cur];

0 commit comments

Comments
 (0)