GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — bpo-40255: Implement Immortal Instances - Optimization 3 by eduardo-elizondo · Pull Request #31490 · python/cpython

Conversation

@eduardo-elizondo

@eduardo-elizondo eduardo-elizondo commented Feb 22, 2022 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Immortalizing Modules After Import

This is an optimization on top of PR19474.

The improvement here uses the assumption that top-level modules and its globals will (most likely) be alive during the entire lifecycle of the runtime. Thus, every time that a top level import happens, it will now immortalize the module and its contents.

Benchmark Results

Overall: 1% slower compared to the master branch

pyperformance results 2to3: Mean +- std dev: [cpython_master] 432 ms +- 15 ms -> [immortal_instances_opt3] 447 ms +- 14 ms: 1.04x slower chaos: Mean +- std dev: [cpython_master] 126 ms +- 4 ms -> [immortal_instances_opt3] 119 ms +- 4 ms: 1.06x faster django_template: Mean +- std dev: [cpython_master] 62.2 ms +- 2.0 ms -> [immortal_instances_opt3] 63.3 ms +- 2.4 ms: 1.02x slower float: Mean +- std dev: [cpython_master] 128 ms +- 4 ms -> [immortal_instances_opt3] 135 ms +- 5 ms: 1.05x slower go: Mean +- std dev: [cpython_master] 244 ms +- 10 ms -> [immortal_instances_opt3] 227 ms +- 6 ms: 1.07x faster hexiom: Mean +- std dev: [cpython_master] 11.5 ms +- 0.6 ms -> [immortal_instances_opt3] 11.3 ms +- 0.3 ms: 1.02x faster html5lib: Mean +- std dev: [cpython_master] 97.9 ms +- 4.2 ms -> [immortal_instances_opt3] 103 ms +- 6 ms: 1.06x slower json_dumps: Mean +- std dev: [cpython_master] 19.2 ms +- 0.7 ms -> [immortal_instances_opt3] 19.8 ms +- 0.5 ms: 1.03x slower logging_format: Mean +- std dev: [cpython_master] 10.4 us +- 0.3 us -> [immortal_instances_opt3] 11.1 us +- 0.5 us: 1.06x slower nqueens: Mean +- std dev: [cpython_master] 159 ms +- 5 ms -> [immortal_instances_opt3] 154 ms +- 3 ms: 1.04x faster pathlib: Mean +- std dev: [cpython_master] 28.5 ms +- 0.7 ms -> [immortal_instances_opt3] 27.9 ms +- 0.9 ms: 1.02x faster pickle: Mean +- std dev: [cpython_master] 16.0 us +- 0.5 us -> [immortal_instances_opt3] 15.6 us +- 0.5 us: 1.03x faster pickle_dict: Mean +- std dev: [cpython_master] 37.3 us +- 0.6 us -> [immortal_instances_opt3] 36.2 us +- 0.8 us: 1.03x faster pickle_pure_python: Mean +- std dev: [cpython_master] 572 us +- 14 us -> [immortal_instances_opt3] 581 us +- 15 us: 1.02x slower pidigits: Mean +- std dev: [cpython_master] 284 ms +- 15 ms -> [immortal_instances_opt3] 276 ms +- 6 ms: 1.03x faster pyflate: Mean +- std dev: [cpython_master] 770 ms +- 28 ms -> [immortal_instances_opt3] 760 ms +- 21 ms: 1.01x faster python_startup: Mean +- std dev: [cpython_master] 12.6 ms +- 0.4 ms -> [immortal_instances_opt3] 12.1 ms +- 0.5 ms: 1.04x faster python_startup_no_site: Mean +- std dev: [cpython_master] 8.89 ms +- 0.39 ms -> [immortal_instances_opt3] 8.55 ms +- 0.45 ms: 1.04x faster raytrace: Mean +- std dev: [cpython_master] 529 ms +- 16 ms -> [immortal_instances_opt3] 540 ms +- 19 ms: 1.02x slower regex_compile: Mean +- std dev: [cpython_master] 233 ms +- 6 ms -> [immortal_instances_opt3] 241 ms +- 5 ms: 1.03x slower regex_dna: Mean +- std dev: [cpython_master] 239 ms +- 6 ms -> [immortal_instances_opt3] 252 ms +- 4 ms: 1.06x slower regex_effbot: Mean +- std dev: [cpython_master] 4.53 ms +- 0.12 ms -> [immortal_instances_opt3] 4.74 ms +- 0.11 ms: 1.05x slower regex_v8: Mean +- std dev: [cpython_master] 33.2 ms +- 0.8 ms -> [immortal_instances_opt3] 34.1 ms +- 1.0 ms: 1.03x slower richards: Mean +- std dev: [cpython_master] 82.8 ms +- 3.7 ms -> [immortal_instances_opt3] 85.9 ms +- 3.8 ms: 1.04x slower scimark_fft: Mean +- std dev: [cpython_master] 571 ms +- 12 ms -> [immortal_instances_opt3] 623 ms +- 23 ms: 1.09x slower scimark_lu: Mean +- std dev: [cpython_master] 195 ms +- 6 ms -> [immortal_instances_opt3] 207 ms +- 7 ms: 1.06x slower scimark_monte_carlo: Mean +- std dev: [cpython_master] 116 ms +- 5 ms -> [immortal_instances_opt3] 120 ms +- 3 ms: 1.03x slower scimark_sor: Mean +- std dev: [cpython_master] 211 ms +- 6 ms -> [immortal_instances_opt3] 216 ms +- 7 ms: 1.02x slower scimark_sparse_mat_mult: Mean +- std dev: [cpython_master] 8.28 ms +- 0.40 ms -> [immortal_instances_opt3] 8.56 ms +- 0.22 ms: 1.03x slower sympy_expand: Mean +- std dev: [cpython_master] 878 ms +- 34 ms -> [immortal_instances_opt3] 831 ms +- 24 ms: 1.06x faster sympy_integrate: Mean +- std dev: [cpython_master] 35.2 ms +- 1.0 ms -> [immortal_instances_opt3] 36.2 ms +- 1.9 ms: 1.03x slower sympy_str: Mean +- std dev: [cpython_master] 514 ms +- 11 ms -> [immortal_instances_opt3] 521 ms +- 18 ms: 1.01x slower unpickle: Mean +- std dev: [cpython_master] 21.5 us +- 0.7 us -> [immortal_instances_opt3] 21.8 us +- 0.5 us: 1.02x slower unpickle_pure_python: Mean +- std dev: [cpython_master] 463 us +- 17 us -> [immortal_instances_opt3] 446 us +- 14 us: 1.04x faster xml_etree_parse: Mean +- std dev: [cpython_master] 245 ms +- 6 ms -> [immortal_instances_opt3] 239 ms +- 8 ms: 1.02x faster xml_etree_generate: Mean +- std dev: [cpython_master] 146 ms +- 4 ms -> [immortal_instances_opt3] 149 ms +- 4 ms: 1.02x slower

Benchmark hidden because not significant (15): deltablue, fannkuch, json_loads, logging_silent, logging_simple, meteor_contest, nbody, pickle_list, spectral_norm, sympy_sum, telco, unpack_sequence, unpickle_list, xml_etree_iterparse, xml_etree_process

Geometric mean: 1.01x slower

Implementation Details

Any time that a new module import happens in PyImport_ImportModuleLevelObject , we now check the current depth of the python stack. If we are at the top level, it then immortalizes the module as well as all the transitive dependencies. Not only that but it also pushes all the found containers into the permanent GC generation since none of these objects should never be collected again.

Module Finalization

This skips over the correct finalization of the immortalized modules since that’s already handled in PR31489.

https://bugs.python.org/issue40255

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
eduardo-elizondo added 4 commits February 20, 2022 10:49
@eduardo-elizondo
bpo-40255: Implement Immortal Instances - Optimization 3
420967a
@eduardo-elizondo
Immortalize module as well
e756b30
@eduardo-elizondo
Only immortalize top level modules
5d806ae
@eduardo-elizondo
Fix tests
e153dc5
@eduardo-elizondo
eduardo-elizondo requested review from brettcannon, encukou, ericsnowcurrently, ncoghlan, pablogsal and warsaw as code owners February 22, 2022 05:28
@bedevere-bot bedevere-bot added the awaiting review label Feb 22, 2022
@the-knights-who-say-ni the-knights-who-say-ni added the CLA signed label Feb 22, 2022
@methane methane added the DO-NOT-MERGE label Feb 22, 2022
@methane
methane marked this pull request as draft February 22, 2022 05:33
methane
methane reviewed Feb 22, 2022
View reviewed changes
Comment thread Modules/gcmodule.c
_Py_SetImmortal(code->co_names);
_Py_SetImmortal(code->co_varnames);
_Py_SetImmortal(code->co_freevars);
_Py_SetImmortal(code->co_cellvars);

@methane methane Feb 22, 2022

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make contents of these tuples immortal too.
Especially, co_consts is important, because LOAD_CONST will INCREF.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
This was referenced Feb 22, 2022
bpo-40255: Implement Immortal Instances - Optimizations Combined #31491
Closed
gh-84436: Implement Immortal Objects #19474
Merged
brettcannon
brettcannon reviewed Feb 22, 2022
View reviewed changes
Comment thread Lib/test/test_builtin.py
false_refcount = sys.getrefcount(False)
smallint_refcount = sys.getrefcount(100)

# Assert that all of these immortal instances have large ref counts

@brettcannon brettcannon Feb 22, 2022

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Assert that all of these immortal instances have large ref counts
# Assert that all of these immortal instances have large ref counts.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/test/test_builtin.py
self.assertGreater(false_refcount, 1e8)
self.assertGreater(smallint_refcount, 1e8)

# Confirm that the refcount doesn't change even with a new ref to them

@brettcannon brettcannon Feb 22, 2022

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Confirm that the refcount doesn't change even with a new ref to them
# Confirm that the refcount doesn't change even with a new ref to them.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Modules/gcmodule.c
}

_Py_SetImmortal(obj);
/* Special case for PyCodeObjects since they don't have a tp_traverse */

@brettcannon brettcannon Feb 22, 2022

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* Special case for PyCodeObjects since they don't have a tp_traverse */
// Special case for PyCodeObjects since they don't have a tp_traverse.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Objects/object.c
#endif
Py_SET_REFCNT(op, 1);
/* Do not use Py_SET_REFCNT to skip the Immortal Instance check. This
* API guarantees that an instance will always be set to a refcnt of 1 */

@brettcannon brettcannon Feb 22, 2022

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* API guarantees that an instance will always be set to a refcnt of 1 */
* API guarantees that an instance will always be set to a refcnt of 1. */

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Python/import.c
if (mod == NULL) {
goto error;
}
// Immortalize top level modules

@brettcannon brettcannon Feb 22, 2022

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Immortalize top level modules
// Immortalize top level modules.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@ezio-melotti ezio-melotti removed the CLA signed label Jul 13, 2022
@eduardo-elizondo eduardo-elizondo mannequin mentioned this pull request Jun 6, 2022
Fixing Copy on Writes from reference counting and immortal objects #84436
Closed
@eduardo-elizondo eduardo-elizondo closed this Apr 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@brettcannon brettcannon brettcannon left review comments
@methane methane methane left review comments
@pablogsal pablogsal Awaiting requested review from pablogsal pablogsal is a code owner
@encukou encukou Awaiting requested review from encukou
@ericsnowcurrently ericsnowcurrently Awaiting requested review from ericsnowcurrently ericsnowcurrently is a code owner
@ncoghlan ncoghlan Awaiting requested review from ncoghlan ncoghlan is a code owner
@warsaw warsaw Awaiting requested review from warsaw warsaw is a code owner
@FFY00 FFY00 Awaiting requested review from FFY00 FFY00 will be requested when the pull request is marked ready for review FFY00 is a code owner
@kumaraditya303 kumaraditya303 Awaiting requested review from kumaraditya303 kumaraditya303 will be requested when the pull request is marked ready for review kumaraditya303 is a code owner
@ZeroIntensity ZeroIntensity Awaiting requested review from ZeroIntensity ZeroIntensity will be requested when the pull request is marked ready for review ZeroIntensity is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting review DO-NOT-MERGE

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

6 participants

@eduardo-elizondo @brettcannon @methane @the-knights-who-say-ni @ezio-melotti @bedevere-bot
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.