[Ray] Actor Pool Map Operator 스케줄러 오버헤드 57% 감소
PR 링크: ray-project/ray#61591 상태: Merged | 변경: +11 / -13
들어가며
Ray Data 파이프라인에서 500개 이상의 액터를 사용할 때 스케줄러의 tick당 오버헤드가 병목이 됩니다. update_resource_usage와 select_actors가 매 tick마다 모든 액터를 순회하는데, 프로파일링 결과 protobuf enum 재해석, 중복 dict lookup, 불필요한 함수 호출 등 Python 오버헤드가 지배적이었습니다.
핵심 코드 분석
Protobuf enum 상수를 모듈 레벨에서 캐싱
Before:
if actor_state in (None, gcs_pb2.ActorTableData.ActorState.DEAD):
return running_actor_state
elif actor_state != gcs_pb2.ActorTableData.ActorState.ALIVE:
assert actor_state == gcs_pb2.ActorTableData.ActorState.RESTARTING
After:
_ACTOR_STATE_DEAD = gcs_pb2.ActorTableData.ActorState.DEAD
_ACTOR_STATE_ALIVE = gcs_pb2.ActorTableData.ActorState.ALIVE
_ACTOR_STATE_RESTARTING = gcs_pb2.ActorTableData.ActorState.RESTARTING
if actor_state in (None, _ACTOR_STATE_DEAD):
return running_actor_state
elif actor_state != _ACTOR_STATE_ALIVE:
assert actor_state == _ACTOR_STATE_RESTARTING
Protobuf의 EnumTypeWrapper.__getattr__는 매 접근마다 문자열 룩업을 수행합니다. 모듈 로드 시 1회만 해석하면 1000개 액터 기준 약 5.3s에서 0.6s로 감소합니다.
_rank_actors에서 dict 조회 1회로 통합
Before:
ranks = [
(
locs_priorities.get(
self._running_actors[actor].actor_location, INT32_MAX
),
self._running_actors[actor].num_tasks_in_flight,
)
for actor in actors
]
After:
return [
(
locs_priorities.get(state.actor_location, INT32_MAX),
state.num_tasks_in_flight,
)
for state in (self._running_actors[actor] for actor in actors)
]
액터당 self._running_actors[actor] 조회가 2회에서 1회로 줄어들고, 각 조회마다 발생하는 ActorHandle.__hash__ 비용이 절반이 됩니다.
왜 이게 좋은가
프로파일링 결과 (1000 액터 기준):
| 함수 | Before | After | 감소 |
|---|---|---|---|
| update_resource_usage | 11.83s | 5.06s | 57% |
| refresh_actor_state | 11.46s | 4.54s | 60% |
| select_actors | 6.82s | 2.76s | 60% |
| _rank_actors | 3.18s | 1.25s | 61% |
- 총 코드 변경은 +11/-13줄로 매우 작지만 효과는 극적입니다
- Python의 동적 속성 조회, dict hashing, 함수 호출 오버헤드를 이해하고 있어야 가능한 최적화입니다
- 핫 루프에서 상수를 로컬 변수로 끌어올리는 것은 CPython 성능 최적화의 기본 기법입니다
참고 자료
관련 포스트
PR Analysis 의 다른글
- 이전글 [vllm] ViT Full CUDA Graph - 비전 인코더 CUDA Graph 완전 지원
- 현재글 : [Ray] Actor Pool Map Operator 스케줄러 오버헤드 57% 감소
- 다음글 [sglang] HiSparse 도입: Sparse Attention 모델을 위한 효율적인 KV 캐시 관리
댓글