Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Free-threaded(nogil) Python Support #28

Open
Yiling-J opened this issue Aug 16, 2024 · 2 comments
Open

Free-threaded(nogil) Python Support #28

Yiling-J opened this issue Aug 16, 2024 · 2 comments
Assignees

Comments

@Yiling-J
Copy link
Owner

Yiling-J commented Aug 16, 2024

Given the architecture of Thine, where the policy logic is implemented in Rust and the key/value map resides in Python, enabling free-threaded support for the Python part should be feasible while keeping the Rust portion single-threaded. Rust is significantly faster than Python, and single-threaded match the design of BP-Wrapper. The change will make the policy read somewhat lossy, but this is intentional and already used in theine-go.

  • add locks(in Python)
  • use sharded map
  • replace keygen with hash()

The hash value is used in the policy as the identity of an object. So rust policy code doesn't need any PyObject. This approach separates the policy component from the main Python code as much as possible, keeping the policy single thread and avoiding the complexities of CPython/PyO3/nogil stuff, also simplifying the code(slower than put everything in Rust, but when Python has better JIT this might be improved). The trade-off is the potential for hash collisions, where multiple objects with the same hash will share the same entry in the policy. However, given Python's significant memory overhead and the often limited cache size, collisions should not be a major issue.

  • only keep tlfu policy, the best one
# old

cache = Cache("tlfu", 10000)

@Memoize(Cache("tlfu", 10000), timedelta(seconds=100))
# new

cache = Cache(10000)

@Memoize(10000, timedelta(seconds=100))
  • refactor read/write buffer, make read buffer lossy
  • update benchmarks, show multithreading nogil performance
@Yiling-J Yiling-J self-assigned this Aug 16, 2024
@Yiling-J Yiling-J mentioned this issue Aug 16, 2024
@Yiling-J Yiling-J pinned this issue Aug 16, 2024
@Yiling-J Yiling-J changed the title Free-threaded Python Support Free-threaded(nogil) Python Support Aug 18, 2024
@Yiling-J
Copy link
Owner Author

Yiling-J commented Aug 26, 2024

related branches:
theine-core: https://github.com/Yiling-J/theine-core/tree/v2
theine: https://github.com/Yiling-J/theine/tree/v2

Changes(WIP):

  • Remove policy param from Cache, there is only one policy tlfu now.
  • Use sharded dict with lock for data storage.
  • Striped read buffer.
  • Use object hash() instead of auto increasing key.
  • Rewrite Rust core, use u64 as key.
  • Use asyncio for proactively expire, now all cache instances will use same event loop for maintance task.

@Yiling-J
Copy link
Owner Author

Yiling-J commented Sep 5, 2024

Related issues:

  1. Tracking issue for no-gil/freethreaded work PyO3/pyo3#4265 (comment)
    I attempted to build without the GIL, and it seems to work.

  2. Instance method performance issue with free threading (3.13rc1) python/cpython#123619
    The instance method has high contention, making it slow. This should be fixed before running scalability benchmarks.

  3. Typed library #27
    The refactor/rewrite is based on this PR, which should be merged first.

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

No branches or pull requests

1 participant