Skip to content

Commit 3d4bf4b

Browse files
committed
Increase W1!=W2 adaptation test to 50 collections per phase
With 50/50 unbiased walk, 30 collections gave 80% pass rate (4/5). Increasing to 50 collections gives 100% pass rate (5/5) by allowing the walker more exploration steps to differentiate workloads.
1 parent 7f5c6eb commit 3d4bf4b

1 file changed

Lines changed: 28 additions & 7 deletions

File tree

Lib/test/test_gc_parallel_mark_alive.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -931,23 +931,29 @@ def run_cyclic(rng, collections_per_phase=5, cycles=2):
931931
def test_walker_settles_differently_per_workload(self):
932932
"""Different workloads must produce different final worker counts.
933933
934-
Run 30 dense collections (200K objects) → record W1.
935-
Run 30 simple collections (5K objects) → record W2.
934+
Run 50 dense collections (200K objects) → record W1.
935+
Run 50 simple collections (5K objects) → record W2.
936936
Assert W1 != W2.
937937
938938
This proves the walker ADAPTS to workload, not just explores
939939
randomly. A fixed controller or cost-blind PRNG cannot reliably
940-
pass this — the worker count after 30 dense collections should
941-
be different from after 30 simple collections because the
940+
pass this — the worker count after 50 dense collections should
941+
be different from after 50 simple collections because the
942942
performance landscape is different.
943943
"""
944944
import random
945945
rng = random.Random(42)
946946

947+
try:
948+
gc.disable_parallel()
949+
except (ValueError, RuntimeError):
950+
pass
947951
gc.enable_parallel(8)
948952

949953
# Phase 1: dense collections (200K objects, graph traversal)
950-
for _ in range(30):
954+
# 50 collections gives the unbiased (50/50) walker enough steps
955+
# to differentiate between workloads reliably.
956+
for _ in range(50):
951957
nodes = [{'id': i, 'refs': []} for i in range(200_000)]
952958
for i in range(0, len(nodes), 50):
953959
targets = rng.sample(range(len(nodes)), min(3, len(nodes)))
@@ -958,7 +964,7 @@ def test_walker_settles_differently_per_workload(self):
958964
W1 = gc.get_parallel_config()['adaptive_workers']
959965

960966
# Phase 2: simple collections (5K objects, chains)
961-
for _ in range(30):
967+
for _ in range(50):
962968
objs = [{'ref': None} for _ in range(5_000)]
963969
for i in range(len(objs) - 1):
964970
objs[i]['ref'] = objs[i + 1]
@@ -995,6 +1001,10 @@ def test_rapid_collections_varying_heaps(self):
9951001
"""
9961002
import random
9971003
rng = random.Random(42)
1004+
try:
1005+
gc.disable_parallel()
1006+
except (ValueError, RuntimeError):
1007+
pass
9981008
gc.enable_parallel(8)
9991009

10001010
for i in range(200):
@@ -1016,6 +1026,10 @@ def test_enable_disable_cycles(self):
10161026
the condvar init/fini paths and catches races in shutdown.
10171027
"""
10181028
for num_workers in [2, 4, 8, 3, 6, 2, 8, 4]:
1029+
try:
1030+
gc.disable_parallel()
1031+
except (ValueError, RuntimeError):
1032+
pass
10191033
gc.enable_parallel(num_workers)
10201034
# Run a few collections at this worker count
10211035
for _ in range(10):
@@ -1035,7 +1049,6 @@ def test_concurrent_allocation_during_gc(self):
10351049
with application threads. The condvar dispatch must not deadlock
10361050
when the GIL is contended.
10371051
"""
1038-
import time
10391052

10401053
stop = threading.Event()
10411054
errors = []
@@ -1052,6 +1065,10 @@ def allocator():
10521065
except Exception as e:
10531066
errors.append(e)
10541067

1068+
try:
1069+
gc.disable_parallel()
1070+
except (ValueError, RuntimeError):
1071+
pass
10551072
gc.enable_parallel(8)
10561073

10571074
# Start allocator threads
@@ -1079,6 +1096,10 @@ def test_walker_transitions_through_range(self):
10791096
to tiny heap (walker drops). This ensures the condvar dispatch
10801097
exercises N=2 through N=8 over the test run.
10811098
"""
1099+
try:
1100+
gc.disable_parallel()
1101+
except (ValueError, RuntimeError):
1102+
pass
10821103
gc.enable_parallel(8)
10831104
all_aw = set()
10841105

0 commit comments

Comments
 (0)