Reduce overhead of PyErr_CheckSignals
Ninguém assumiu esta issue ainda.
- Linguagem predominante
- Python
- Estrelas
- 77.2k
- Forks
- 36k
- Métricas de merge de PRs
- Métricas de PR pendentes
Descrição
Feature or enhancement
Proposal:
PyErr_CheckSignals() is the API long-running C loops use to stay interruptible. In the common case (no signal arrived) the call currently does, in order:
_PyRunRemoteDebugger()(since gh-131591, 3.14): a call that fetches the interpreter config via_PyInterpreterState_GetConfig()before looking at the pending flag;_Py_ThreadCanHandleSignals():_Py_IsMainThread()callsPyThread_get_thread_ident()and thereforepthread_self(), plus_Py_IsMainInterpreter();- only then
_PyErr_CheckSignalsTstate(), whose first line is the cheapis_trippedtest that returns immediately.
That is about 100 instructions per call.
Proposal
Test the cheap flags first, without changing what is done when they are set:
_PyErr_CheckSignalsTstate()does the main-thread check itself, after its existingis_trippedtest, soPyErr_CheckSignals()and the eval loop just call it; the handler-running body moves to an out-of-line helper so the early return stays cheap;_PyRunRemoteDebugger()testsdebugger_pending_callbefore fetching the config.
Results
Non-PGO build, pyperf:
| Benchmark | main | branch |
|---|---|---|
| str(12345) | 68.6 ns | 56.8 ns: 1.21x faster |
| repr(list(range(100))) | 3.06 us | 2.36 us: 1.29x faster |
| ', '.join(map(str, range(100))) | 6.90 us | 5.67 us: 1.22x faster |
| '%s=%r' % (k, v) | 192 ns | 177 ns: 1.08x faster |
| print(*range(100), file=f) | 15.6 us | 13.5 us: 1.16x faster |
| csv.writer: 100 rows of 10 ints | 72.5 us | 60.1 us: 1.21x faster |
| repr(dataclass with 5 fields) | 805 ns | 720 ns: 1.12x faster |
| a * b (10 x 10 digits) | 159 ns | 102 ns: 1.56x faster |
| a // c (10 // 2 digits) | 151 ns | 121 ns: 1.24x faster |
Notes: the gain for the arithmetic cases are not too important, they can be handled directly as well. See https://github.com/python/cpython/issues/157742.
Has this already been discussed elsewhere?
Related: gh-131591, gh-133465
Has this already been discussed elsewhere?
No response given
Links to previous discussion of this feature:
No response
Linked PRs
- gh-157748
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Direção de pesquisa
Comece lendo PyErr_CheckSignals(), _PyErr_CheckSignalsTstate() e _PyRunRemoteDebugger(), concentrando-se na ordem indicada das verificações baratas de flags e do tratamento de sinais. Compare o comportamento proposto e os benchmarks com o PR vinculado gh-157748; a issue estará concluída quando o caminho sem sinais for mais barato, sem alterar o comportamento quando os flags estiverem definidos.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- c, python
- Domínio
- performance
- Tipo de issue
- Funcionalidade
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Status de atividade
- Estagnada
- Clareza
- Claramente especificada
- Facilidade para iniciantes
- 25/100