Skip to content

Specialize long tail of binary operations using a table. #100239

Open
@markshannon

Description

@markshannon

There is a desire to specialize the remaining binary operations (including binary subscript).
However adding more and more specialized instructions is likely to make performance worse.

This idea is to have a lookup table of types pairs and function pointers. This is less efficient than inlining the code, but more extensible.

A single instruction can then support up to 256 specializations.
This will only work for immutable classes.

struct table_entry {
    PyTypeObject *left;
    PyTypeObject *left;
    binaryfunc *func;
};

TARGET(BINARY_OP_TABLE) {
    PyObject *lhs = SECOND();
    PyObject *rhs = TOP();
    Cache *cache = GET_CACHE();
    struct table_entry* entry = &THE_TABLE[cache->table_index];
    DEOPT_IF(Py_TYPE(lhs) != entry->left);
    DEOPT_IF(Py_TYPE(rhs) != entry->right);
    PyObject *res = entry->func(lhs, rhs);
    if (res == NULL) {
        goto error;
    }
    STACK_SHRINK(1);
    Py_DECREF(lhs);
    Py_DECREF(rhs);
    SET_TOP(res);
    DISPATCH();
}

An ancillary mapping of (left, right) -> index will be needed for efficient specialization.

It is probably worth keeping the most common operations int + int, float + float, etc. inline.

We can replace BINARY_SUBSCR with BINARY_OP ([]) to allow effective specialization of BINARY_SUBSCR
E.g. subscripting array.array[int] can be handled with the registration mechanism described below.

Registering binary functions at runtime

faster-cpython/ideas#162

Linked PRs

Metadata

Metadata

Assignees

Labels

interpreter-core(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagetype-featureA feature request or enhancement

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions