본문으로 건너뛰기

스레드 모델

활성 상태의 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()은 취소 경로입니다. 취소 후, 진행 중인 풀 요청은 차단 해제되고 푸시 작업은 중단되어야 합니다. 종료 중인 런타임에 계속 푸시하지 마십시오.

처리량 스레드 구조​

앱에서 푸시하는 실시간 또는 높은 처리량 그래프의 경우, 두 개의 애플리케이션 스레드로 시작합니다.

  1. 프로듀서 스레드는 입력을 읽고, stream_id / frame_id를 기록하고, 선택한 OverflowPolicy에 따라 try_push(...) 또는 push(...)를 호출합니다.
  2. 컨슈머 스레드는 지속적으로 데이터를 가져오고, 런타임 기반 버퍼에 고정되기 전에 출력을 해제하거나 복사합니다.

자체 큐를 중심으로 더 많은 애플리케이션 스레드를 추가하되, 동일한 Run 객체를 중심으로 추가하지는 마십시오. 핵심 루프를 단순하게 만드십시오. 단순함이 빠릅니다.

추가 자료​