|
4 | 4 | This allows multiple threads to run resampling in parallel, which is critical |
5 | 5 | for performance in multi-threaded applications. |
6 | 6 | """ |
| 7 | +import platform |
| 8 | +import sys |
7 | 9 | import threading |
8 | 10 | import time |
9 | 11 | import numpy as np |
|
12 | 14 | import samplerate |
13 | 15 |
|
14 | 16 |
|
| 17 | +def is_arm_mac(): |
| 18 | + """Check if running on ARM-based macOS (Apple Silicon).""" |
| 19 | + return sys.platform == 'darwin' and platform.machine() == 'arm64' |
| 20 | + |
| 21 | + |
15 | 22 | def _resample_work(data, ratio, converter_type, results, index): |
16 | 23 | """Worker function that performs resampling.""" |
17 | 24 | start = time.perf_counter() |
@@ -86,15 +93,21 @@ def test_resample_gil_release_parallel(num_threads, converter_type): |
86 | 93 | parallel_time = time.perf_counter() - start |
87 | 94 |
|
88 | 95 | # If GIL is properly released, parallel should be significantly faster |
89 | | - # We expect at least 1.2x speedup for 2 threads, 1.35x for 4+ threads |
90 | | - # (accounting for overhead, non-perfect parallelization, and CI constraints) |
91 | | - expected_speedup = 1.2 if num_threads == 2 else 1.35 |
| 96 | + # We expect at least 1.3x speedup for 2 threads, 1.5x for 4 threads |
| 97 | + # (accounting for overhead and non-perfect parallelization) |
| 98 | + # ARM Mac has different threading characteristics, especially for faster converters |
| 99 | + if is_arm_mac(): |
| 100 | + # More relaxed expectations for ARM architecture |
| 101 | + expected_speedup = 1.15 if num_threads == 2 else 1.25 |
| 102 | + else: |
| 103 | + expected_speedup = 1.2 if num_threads == 2 else 1.35 |
92 | 104 | speedup = sequential_time / parallel_time |
93 | 105 |
|
94 | 106 | print(f"\n{converter_type} with {num_threads} threads:") |
95 | 107 | print(f" Sequential: {sequential_time:.4f}s") |
96 | 108 | print(f" Parallel: {parallel_time:.4f}s") |
97 | 109 | print(f" Speedup: {speedup:.2f}x") |
| 110 | + print(f" Platform: {'ARM Mac' if is_arm_mac() else platform.machine()}") |
98 | 111 | print(f" Individual thread times: {[f'{t:.4f}s' for t in results]}") |
99 | 112 |
|
100 | 113 | assert speedup >= expected_speedup, ( |
@@ -142,13 +155,17 @@ def test_resampler_process_gil_release_parallel(num_threads, converter_type): |
142 | 155 |
|
143 | 156 | parallel_time = time.perf_counter() - start |
144 | 157 |
|
145 | | - expected_speedup = 1.2 if num_threads == 2 else 1.35 |
| 158 | + if is_arm_mac(): |
| 159 | + expected_speedup = 1.15 if num_threads == 2 else 1.25 |
| 160 | + else: |
| 161 | + expected_speedup = 1.2 if num_threads == 2 else 1.35 |
146 | 162 | speedup = sequential_time / parallel_time |
147 | 163 |
|
148 | 164 | print(f"\n{converter_type} Resampler.process() with {num_threads} threads:") |
149 | 165 | print(f" Sequential: {sequential_time:.4f}s") |
150 | 166 | print(f" Parallel: {parallel_time:.4f}s") |
151 | 167 | print(f" Speedup: {speedup:.2f}x") |
| 168 | + print(f" Platform: {'ARM Mac' if is_arm_mac() else platform.machine()}") |
152 | 169 | print(f" Individual thread times: {[f'{t:.4f}s' for t in results]}") |
153 | 170 |
|
154 | 171 | assert speedup >= expected_speedup, ( |
@@ -203,13 +220,17 @@ def producer(): |
203 | 220 |
|
204 | 221 | # Callback resampler has more GIL contention due to callback invocation, |
205 | 222 | # so we expect lower speedup |
206 | | - expected_speedup = 1.2 |
| 223 | + if is_arm_mac(): |
| 224 | + expected_speedup = 1.1 |
| 225 | + else: |
| 226 | + expected_speedup = 1.2 |
207 | 227 | speedup = sequential_time / parallel_time |
208 | 228 |
|
209 | 229 | print(f"\n{converter_type} CallbackResampler with {num_threads} threads:") |
210 | 230 | print(f" Sequential: {sequential_time:.4f}s") |
211 | 231 | print(f" Parallel: {parallel_time:.4f}s") |
212 | 232 | print(f" Speedup: {speedup:.2f}x") |
| 233 | + print(f" Platform: {'ARM Mac' if is_arm_mac() else platform.machine()}") |
213 | 234 | print(f" Individual thread times: {[f'{t:.4f}s' for t in results]}") |
214 | 235 |
|
215 | 236 | assert speedup >= expected_speedup, ( |
|
0 commit comments