python / python/cpython

Optimize reference tracking and eliminate branching during returns and yields

Ouverte
#144,540 5 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

3.15 interpreter-core topic-JIT
Langage dominant
Python
Étoiles
77.2k
Forks
35.9k
Métriques de merge des PR
Métriques de PR en attente

Description

There are a few optimizations we can make to returns and yields, but they are somewhat related so I'm grouping them into a single issue.

During a return, the VM needs to make the returned reference "heap safe" (convert any borrowed references to strong references) and then pop and clear the frame, which can involve quite a lot of decrefs.
During a yield, the VM needs to make the returned reference heap safe and then pop the frame, but not clear it.

We want to minimize the amount of refcounting operations that we do.

Before we can do much else, we should split RETURN_VALUE and YIELD_VALUE into micro-ops:

macro(RETURN_VALUE) = _MAKE_HEAP_SAFE + _RETURN_VALUE

macro(YIELD_VALUE) = _MAKE_HEAP_SAFE + _YIELD_VALUE

so that we can optimize the uops independently

Eliminate making heap safe if we know that reference already is

If TOS is a strong reference _MAKE_HEAP_SAFE -> _NOP

Avoid the branch in _RETURN_VALUE by splitting into _RETURN_VALUE_GEN and _RETURN_VALUE_FUNC

To avoid using up opcodes, we'll need to do this in the JIT, not the interpreter.

Track borrows/immortals to optimize clearing frames

E.g. if a frame has four local variables, a, b, c, d but we can tell that a and d are immortal, or borrowed, then instead of looping over all the variables, we could emit code just to decref b and c.
This might end up bloating the code, as we would need to inline the decrefs, but it could be quite a lot faster.

Linked PRs
  • gh-144414
  • gh-146320

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par lire les macros RETURN_VALUE et YIELD_VALUE, puis suivez _MAKE_HEAP_SAFE, _RETURN_VALUE et _YIELD_VALUE à travers l’interpréteur et le JIT. Comparez les travaux liés gh-144414 et gh-146320 avant de définir le périmètre ; la tâche serait considérée comme terminée si les chemins de return et de yield étaient optimisés indépendamment et si le comptage de références inutile était réduit, sans régression du comportement.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
compilers, performance
Type d'issue
Refactorisation
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
À clarifier
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.