Skip to content

Conversation

Copy link

Copilot AI commented Nov 25, 2025

  • Analyze previous PRs (Release GIL while resampling #1, Enhance GIL management and error handling in resampling operations #4) that introduced GIL release for resampling operations
  • Understand the current implementation in src/samplerate.cpp
  • Benchmark single-threaded performance with current implementation
  • Identify threshold for data size where GIL release benefit exceeds overhead
  • Implement conditional GIL release based on data size threshold (1000 frames)
  • Add threshold constant with documentation
  • Implement user-controllable release_gil parameter for explicit control
  • Test the fix with benchmarks to verify improvement
  • Run existing tests to verify no regressions (204 tests pass)
  • Add specific tests for release_gil parameter behavior
  • Run code review and security checks
  • Update documentation with the new release_gil parameter

Summary

This PR addresses the issue where releasing the GIL during resampling operations added overhead that impaired single-threaded performance for small data sizes.

Root Cause

The GIL release/acquire overhead (~1-5 µs) was significant for small data sizes where the actual resampling work only took 20-100 µs.

Solution

Added a new release_gil parameter to all resampling methods that gives users explicit control:

# Default: automatic based on data size (>= 1000 frames)
samplerate.resample(data, ratio)

# Force GIL release for multi-threaded applications
samplerate.resample(data, ratio, release_gil=True)

# Disable GIL release for single-threaded, small data
samplerate.resample(data, ratio, release_gil=False)

Results

  • Small data (<1000 frames): No GIL release overhead, optimal single-threaded performance
  • Large data (≥1000 frames): GIL released, enables 2.29x speedup with 4 threads
  • User control: Applications can override the default behavior
  • All 204 tests pass
  • No security vulnerabilities detected
Original prompt

Review the changes made in previous pull requests - the performance gained by releasing the GIL appears to have impaired the single threading performance.

Identify possible causes, benchmark to verify the cause and implement a solution.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 5 commits November 25, 2025 03:57
Co-authored-by: shauneccles <21007065+shauneccles@users.noreply.github.com>
Introduces GIL_RELEASE_THRESHOLD_FRAMES (1000) to only release the GIL
when the data size is large enough that resampling work dominates the
GIL release/acquire overhead (~1-5 µs). This improves single-threaded
performance for small data sizes while maintaining multi-threading
benefits for large data sizes.

- Resampler.process(): conditional GIL release
- CallbackResampler.read(): conditional GIL release
- resample(): conditional GIL release
- Added tests for conditional GIL release behavior
- Updated .gitignore to exclude compiled extensions

Co-authored-by: shauneccles <21007065+shauneccles@users.noreply.github.com>
Use lambdas to extract the common resampling logic, making the
conditional GIL release pattern more maintainable.

Co-authored-by: shauneccles <21007065+shauneccles@users.noreply.github.com>
Co-authored-by: shauneccles <21007065+shauneccles@users.noreply.github.com>
Co-authored-by: shauneccles <21007065+shauneccles@users.noreply.github.com>
Copilot AI changed the title [WIP] Investigate GIL release impact on single threading performance Add conditional GIL release based on data size threshold Nov 25, 2025
Copilot AI requested a review from shauneccles November 25, 2025 04:13
@shauneccles
Copy link
Member

@copilot Look deeper - is there a better way to handle this, or to resolve or otherwise manage this issue.

Copilot AI and others added 2 commits November 27, 2025 10:09
Instead of using only a fixed threshold, users can now explicitly control
GIL release behavior via a new release_gil parameter:

- None or "auto" (default): Release GIL only for large data (>= 1000 frames)
- True: Always release GIL (best for multi-threaded applications)
- False: Never release GIL (best for single-threaded, small data)

This provides better control compared to the previous threshold-only approach:
- Single-threaded applications can use release_gil=False to avoid overhead
- Multi-threaded applications can use release_gil=True for maximum parallelism
- Default "auto" mode balances both use cases

Co-authored-by: shauneccles <21007065+shauneccles@users.noreply.github.com>
Co-authored-by: shauneccles <21007065+shauneccles@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 27, 2025

@copilot Look deeper - is there a better way to handle this, or to resolve or otherwise manage this issue.

Investigated deeper and implemented a better solution in commit 3f0df5f.

Instead of only using a fixed threshold, users now have explicit control via a release_gil parameter:

# Default "auto" mode (threshold-based)
samplerate.resample(data, ratio)

# Force GIL release for multi-threaded apps
samplerate.resample(data, ratio, release_gil=True)

# Disable GIL release for single-threaded, small data
samplerate.resample(data, ratio, release_gil=False)

This approach:

  1. Keeps the smart default that balances both use cases
  2. Gives users full control when they know their workload
  3. Is properly documented with clear guidance

@shauneccles shauneccles marked this pull request as ready for review November 27, 2025 10:20
@shauneccles
Copy link
Member

@copilot Update the documentation with this new parameter

Added a new "Multi-threading and GIL Control" section explaining:
- The release_gil parameter and its three modes (None/auto, True, False)
- When to use each mode for optimal performance
- Examples for resample(), Resampler.process(), and CallbackResampler.read()

Co-authored-by: shauneccles <21007065+shauneccles@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 27, 2025

@copilot Update the documentation with this new parameter

Added documentation for the release_gil parameter in commit 3f3b06f.

Updated README.md with a new "Multi-threading and GIL Control" section that explains the three modes (None/auto, True, False) and when to use each for optimal performance.

@shauneccles shauneccles merged commit d86c1be into main Nov 27, 2025
10 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants