[Triton] SWP 루프 로우어링에서 barrier 위치 결정 로직 수정
PR 링크: triton-lang/triton#8732 상태: Merged | 변경: +283 / -22
들어가며
Software Pipelining(SWP)에서 MMA 연산이 "완료"되었음을 표시하는 barrier의 위치는, tmem_load 또는 non-pipelined operand 중 더 늦게 등장하는 것을 기준으로 결정된다. 기존에는 schedule.isOpBefore를 사용했는데, 이는 operand의 스케줄 순서를 비교할 뿐 실제 루프 body에서의 실행 순서를 반영하지 못했다.
핵심 코드 분석
Before
std::optional<Operation *> latestSyncPoint;
for (auto user : alloc->getUsers()) {
if (auto load = dyn_cast<ttng::TMEMLoadOp>(user)) {
if (!latestSyncPoint || schedule.isOpBefore(load, *latestSyncPoint)) {
latestSyncPoint = load;
}
}
}
isOpBefore는 스케줄 단계(stage/cluster)만 비교하여, MMA 이전에 스케줄된 operand가 MMA 이후에 실행되는 경우를 잘못 판단할 수 있다.
After
llvm::SmallDenseSet<Operation *> syncCandidates;
for (auto user : alloc->getUsers()) {
if (auto load = dyn_cast<ttng::TMEMLoadOp>(user)) {
syncCandidates.insert(load);
}
}
// ... non-pipelined operand defs도 syncCandidates에 추가
// MMA 이후 linearized schedule에서 첫 번째 sync candidate를 찾음
auto linearizedSchedule = schedule.linearized(forOp, mma);
std::optional<Operation *> latestSyncPoint =
linearizedSchedule.findNext(
[&](Operation *op) { return syncCandidates.contains(op); });
LinearizedIterator (Schedule.h)
class LinearizedIterator {
// MMA에서 시작하여, stage/cluster/IR 순서로 순회
// stage 경계를 넘을 때 stage limit 증가
// 원형 순회로 wrap-around 처리
std::optional<Operation *>
findNext(std::function<bool(Operation *)> predicate);
};
왜 이게 좋은가
- 정확한 실행 순서: linearized schedule은 (stage, cluster, IR 순서)의 3단계 정렬을 반영하여, 실제 실행 순서에 기반한 판단을 제공한다.
- 재사용 가능한 API:
LinearizedIterator는 forOp의 스케줄을 순회하는 범용 도구로, 다른 패스에서도 활용 가능하다. - MMA 이후 기준: barrier는 반드시 MMA 이후에 등장하는 sync point를 기준으로 배치되어야 한다는 불변 조건을 명시적으로 구현한다.
정리
Software Pipelining에서 동기화 지점의 정확한 배치는 정확성과 성능 모두에 영향을 미친다. 이 PR은 linearized schedule iterator라는 범용 도구를 도입하여, 스케줄 순서와 실행 순서의 불일치 문제를 근본적으로 해결한다.
참고 자료
이 글은 AI 도구의 도움을 받아 작성되었습니다.
관련 포스트
PR Analysis 의 다른글
- 이전글 [Triton] AMD RDNA에서 matmul_ogs 설정 최적화 — 최대 46% 성능 향상
- 현재글 : [Triton] SWP 루프 로우어링에서 barrier 위치 결정 로직 수정
- 다음글 [Ray] Ray gRPC 토큰 인증 최적화 -- shared_ptr 캐싱
댓글