The copy.copy and copy.deepcopy operations running on different objects in different threads should be able to run independently. The scaling is not good: output of the ftscalingbench.py with added benchmarks:
Running benchmarks with 8 threads
shallow_copy 4.6x slower
deepcopy 2.3x slower
object_cfunction 5.9x faster
cmodule_function 5.9x faster
object_lookup_special 5.5x faster
mult_constant 5.6x faster
generator 4.9x faster
pymethod 5.2x faster
pyfunction 4.5x faster
module_function 5.0x faster
load_string_const 5.6x faster
load_tuple_const 5.9x faster
create_pyobject 2.3x faster
create_closure 7.1x faster
create_dict 3.3x faster
thread_local_read 3.3x faster
There are at least two reasons:
- The
copymodule uses module level variables in thecopy.copyandcopy.deepcopymethods. - The
_copy_atomic_types(and some similar data structures) is asetwhich requires locking for membership testing.
Linked PRs
- gh-132657: Add free-threading scaling benchmark for copy.copy and copy.deepcopy #132658
- gh-132657: Avoid locking in frozenset.__contains__ #132659
- gh-132657: Avoid locks and refcounts in frozenset operations #136107
- GH-132657: Add lock-free set contains implementation #132290
- gh-132657: Make deepcopy and copy scale with free-threading #138429
- gh-132657: optimize
PySet_Containsforfrozensets#141183 - [3.14] gh-132657: avoid locks and refcounting in
frozensetlookups (GH-136107) #141772 - [3.14] gh-132657: optimize
PySet_Containsforfrozenset(GH-141183) #141773 - gh-132657: revert lock-free set contains #142733
- gh-132657: Use stronger memory ordering for so->mask. #142735
- gh-132657: Add maybe_enable_deferred_ref_count(). #142843
- gh-132657: Improve performance in specialize_dict_access_hint() via adding specialization for PY_GIL_DISABLED #144886