스레드 모델
활성 상태의 Run은 프레임워크 및 런타임 스레드에서 작업을 수행합니다. 애플리케이션은 이러한 스레드를 관리할 필요가 없지만, 자체 푸시, 풀, 콜백 및 종료 코드를 체계적으로 유지해야 합니다.
스레드 개요
일반적인 Run의 경우:
| 스레드 | 역할 | 소유자 |
|---|---|---|
| GStreamer 스트리밍 스레드 | 소스, 변환 및 싱크 경로를 통해 버퍼를 이동합니다. | GStreamer 런타임 |
| MLA 디스패처 스레드 | MLA 작업을 제출하고 완료를 수집합니다. | Neat 런타임 |
| EV74 / CVU 디스패처 스레드 | CVU 측 커널을 제출하고 완료를 확인합니다. | Neat 런타임 |
| 풀 측 대기 및 버스 감시자 | 출력 샘플을 공개 큐로 이동하고 런타임 오류를 보고합니다. | Neat 런타임 |
| 애플리케이션 스레드 | Graph.build(...), Graph.run(...), Run.push(...), Run.pull(...), Run.stop() 또는 콜백을 호출합니다. | 애플리케이션 |
그래프 조각, 소스 노드 및 싱크 노드는 런타임 작업을 추가할 수 있지만, 규칙은 동일하게 유지됩니다. 공개 Run은 애플리케이션이 제어하는 핸들입니다.
애플리케이션 코드 실행 위치
사용자 코드는 다음 위치에 나타납니다.
- 직접 API 호출:
build(...),run(...),push(...),try_push(...),pull(...),close_input(),stop()및close()는 해당 API를 호출하는 애플리케이션 스레드에서 실행됩니다. - 드롭 콜백:
RunOptions.on_input_drop은 푸시 경로에서 실행됩니다. 짧게 유지하고, 개수를 세고 반환합니다. - 텐서 콜백:
Graph::set_tensor_callback(...)은 C++ 콜백 스타일의 소비입니다. 콜백을 짧게 유지하십시오. 긴 작업은 런타임 경로에 역압력을 가합니다. - 사용자 지정 노드 설명: 공개 노드 구성 및 그래프 구성은 빌드 시간에 애플리케이션 스레드에서 발생합니다.
콜백에 시간이 오래 걸리는 작업을 숨기지 마십시오. 콜백에서 많은 작업을 수행해야 하는 경우 샘플을 자체 큐로 전달하고 반환합니다.
잠금 규칙
API에 다른 내용이 명시되어 있지 않은 한 Graph, Run, Tensor 및 Sample을 단일 소유 객체로 취급합니다.
지원되는 패턴:
- 하나의 프로듀서 스레드가
push(...)또는try_push(...)를 호출합니다. - 하나의 컨슈머 스레드가
pull(...)를 호출합니다. - 다른 코디네이터 스레드가 종료 중에
stop()를 호출할 수 있습니다.
위험한 패턴:
- 여러 프로듀서 스레드가 잠금 없이 동일한
Run에 푸시합니다. - 여러 컨슈머 스레드가 명확한 소유권 규칙 없이 동일한 출력에서 풀합니다.
- 콜백이 동일한
Run으로 다시 호출되고 더 많은 작업을 기다립니다.
여러 프로듀서가 필요한 경우 Run.push(...)를 호출하기 전에 액세스를 직렬화하십시오. 여러 컨슈머가 필요한 경우 Neat에서 하나의 스레드가 풀한 후 분산하십시오.
종료 및 취소
의도에 맞는 종료 기본값을 사용하십시오.
| 의도 | 사용 |
|---|---|
| 마지막 입력 후 대기 중인 작업을 완료합니다. | run.close_input()를 호출한 다음 더 이상 출력이 도착하지 않거나 PullStatus::Closed가 반환될 때까지 풀합니다. |
| 즉시 중지하고 대기 중인 작업을 해제합니다. | run.stop() |
| 런타임 리소스를 해제합니다. | run.close()를 사용하거나 Run 객체가 범위를 벗어나도록 합니다. |
stop()은 취소 경로입니다. 취소 후, 진행 중인 풀 요청은 차단 해제되고 푸시 작업은 중단되어야 합니다. 종료 중인 런타임에 계속 푸시하지 마십시오.
처리량 스레드 구조
앱에서 푸시하는 실시간 또는 높은 처리량 그래프의 경우, 두 개의 애플리케이션 스레드로 시작합니다.
- 프로듀서 스레드는 입력을 읽고,
stream_id/frame_id를 기록하고, 선택한OverflowPolicy에 따라try_push(...)또는push(...)를 호출합니다. - 컨슈머 스레드는 지속적으로 데이터를 가져오고, 런타임 기반 버퍼에 고정되기 전에 출력을 해제하거나 복사합니다.
자체 큐를 중심으로 더 많은 애플리케이션 스레드를 추가하되, 동일한 Run 객체를 중심으로 추가하지는 마십시오. 핵심 루프를 단순하게 만드십시오. 단순함이 빠릅니다.
추가 자료
- 그래프 실행 — 런타임 라이프사이클, 처리량, 측정 및 역압.
Run— 공개 런타임 객체.- 비동기 방식과 동기 방식의 타이밍 모델 — 작업이 발생하는 시점과 호출이 반환되는 시점.