Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 43 additions & 3 deletions vllm/distributed/device_communicators/shm_broadcast.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,51 @@


class SpinTimer:
"""Base spin timer that yields to the scheduler on each spin."""

def record_activity(self):
pass

def spin(self):
sched_yield()


class SpinBackoffTimer(SpinTimer):
"""
Spin timer with periodic backoff to prevent livelock under high contention.

Under sustained high load, pure sched_yield() can cause livelock when
multiple processes are spinning on shared memory. This timer adds a small
sleep every N spins to break potential livelock patterns.

The backoff interval is tuned to add ~1us of delay per spin on average,
which is enough to break livelocks without significantly impacting latency.
"""

def __init__(self, backoff_interval: int = 1000, backoff_sleep_us: float = 1000):
"""
Args:
backoff_interval: Number of spins between backoff sleeps
backoff_sleep_us: Backoff sleep duration in microseconds
"""
self._spin_count = 0
self._backoff_interval = backoff_interval
self._backoff_sleep_s = backoff_sleep_us / 1_000_000

def record_activity(self):
# Reset spin count on activity to maintain low latency during normal ops
self._spin_count = 0

def spin(self):
self._spin_count += 1
if self._spin_count >= self._backoff_interval:
# Periodic backoff to break potential livelock
time.sleep(self._backoff_sleep_s)
self._spin_count = 0
else:
sched_yield()


class SpinSleepTimer(SpinTimer):
"""
In setups which have long inactivity periods it is desirable to reduce
Expand Down Expand Up @@ -312,7 +350,8 @@
self.local_reader_rank = -1
# rank does not matter for remote readers
self._is_remote_reader = False
self._read_spin_timer = SpinTimer()
self._read_spin_timer = SpinBackoffTimer()
self._write_spin_timer = SpinBackoffTimer()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

While _write_spin_timer is correctly initialized here to use the new backoff strategy, its usage in acquire_write appears to be incomplete. The record_activity() method of the timer is never called after a successful write operation. This is inconsistent with the acquire_read method, which does call record_activity() on its timer after a successful read.

The docstring for record_activity in SpinBackoffTimer states it is for 'maintain[ing] low latency during normal ops'. By not calling it, the writer's spin counter is never reset on success. This leads to periodic sleeps even during normal, non-congested operations, which may introduce a small performance overhead and contradicts a stated goal of the PR to 'preserve low latency during normal operations'.

To ensure consistency and optimal performance in non-congested scenarios, consider calling self._write_spin_timer.record_activity() in the acquire_write method after a write operation succeeds, before the loop is broken. This would align the writer's behavior with the reader's.


self.handle = Handle(
local_reader_ranks=local_reader_ranks,
Expand Down Expand Up @@ -352,7 +391,7 @@
self.remote_socket = None

self._read_spin_timer = (
SpinSleepTimer() if envs.VLLM_SLEEP_WHEN_IDLE else SpinTimer()
SpinSleepTimer() if envs.VLLM_SLEEP_WHEN_IDLE else SpinBackoffTimer()

Check failure on line 394 in vllm/distributed/device_communicators/shm_broadcast.py

View workflow job for this annotation

GitHub Actions / pre-commit

Incompatible types in assignment (expression has type "SpinTimer", variable has type "SpinBackoffTimer") [assignment]

Check failure on line 394 in vllm/distributed/device_communicators/shm_broadcast.py

View workflow job for this annotation

GitHub Actions / pre-commit

Incompatible types in assignment (expression has type "SpinTimer", variable has type "SpinBackoffTimer") [assignment]

Check failure on line 394 in vllm/distributed/device_communicators/shm_broadcast.py

View workflow job for this annotation

GitHub Actions / pre-commit

Incompatible types in assignment (expression has type "SpinTimer", variable has type "SpinBackoffTimer") [assignment]

Check failure on line 394 in vllm/distributed/device_communicators/shm_broadcast.py

View workflow job for this annotation

GitHub Actions / pre-commit

Incompatible types in assignment (expression has type "SpinTimer", variable has type "SpinBackoffTimer") [assignment]
)
else:
self.buffer = None # type: ignore
Expand Down Expand Up @@ -422,7 +461,8 @@
# we need to wait until it is read by all readers

# Release the processor to other threads
sched_yield()
# Use spin timer with backoff to prevent livelock under high contention

Check failure on line 464 in vllm/distributed/device_communicators/shm_broadcast.py

View workflow job for this annotation

GitHub Actions / pre-commit

Ruff (E501)

vllm/distributed/device_communicators/shm_broadcast.py:464:89: E501 Line too long (91 > 88)
self._write_spin_timer.spin()

# if we time out, raise an exception
elapsed = time.monotonic() - start_time
Expand Down
Loading