정의
논리 실행 시간(logical execution time, LET)은 실제 실행 시간을 추상해 버리는 실시간 프로그래밍 추상이다. 프로그램 입력을 읽는 때부터 출력을 쓰는 때까지 걸리는 시간을, 그 프로그램을 실행하는 데 실제로 얼마나 걸리는지와 무관하게 정한다.[1]
이 추상의 근거는 관찰 하나다 — 실시간 프로그램의 유의미한 거동을 정하는 것은 입력을 언제 읽고 출력을 언제 쓰느냐이지, 프로그램이 코드를 실행하고 있는 때가 언제냐가 아니다. 2000년 시간 구동 프로그래밍 언어 Giotto와 함께 도입된 뒤 논쟁적인 발상에서 실시간 프로그래밍의 잘 이해된 원리로 자리 잡았다.
이 계열의 다른 추상과 견주면 자리가 뚜렷해진다. Zero Execution Time은 실행 플랫폼이 무한히 빠르다고 보아 입출력을 포함한 실행 시간을 0으로 가정하며, 동기 반응형 프로그래밍의 핵심 추상이다. Bounded Execution Time은 실행 시간을 추상하는 대신 데드라인으로 묶으며, 실시간 스케줄링 이론이 서 있는 자리다. 논리 실행 시간은 둘 모두에서 영감을 받았다 — 입력을 0의 시간에 읽고, 실행하고, 논리 실행 시간이 다 흐른 바로 그 시점에 다시 0의 시간으로 출력을 쓰면 실행이 옳은 것이 되며, 구간의 끝은 데드라인 노릇을 한다.[1]
구간과 물리적 실행
구간의 두 끝점은 release와 terminate다. release 시점에 입력을 읽고 terminate 시점에 출력을 쓰며, 그 사이에서 프로그램이 실행된다. 프로그램이 구간이 다 흐르기 전에 실행을 마쳐도 출력 쓰기는 구간이 끝날 때까지 미뤄진다.[2]
물리적으로는 그 구간 안에서 활성화와 시작, 선점과 재개, 종료가 벌어진다. 그 시점들이 어떻게 흩어지든 바깥에서 관측되는 타이밍은 달라지지 않는다. 구간 안의 실행이 언제 일어났는지를 나타내는 값들은 타이밍 파라미터에서 다룬다.
결정성
제약 없는 통신 방식, 곧 태스크가 아무 때나 읽고 쓰게 두는 방식의 문제는 실행 지터에서 오는 비결정성이다. 결과가 한 태스크의 활성화 구간 안에서 다른 태스크들이 어떻게 끼어드느냐에 크게 좌우되고, 이 흔들림은 인과 사슬로 이어지면서 종단 간 지연의 큰 편차로 자란다. 논리 실행 시간 모델은 통신 규칙을 엄격히 강제해 이 지터에 대해 견고해진다 — 태스크는 언제나 활성화 구간의 처음에 데이터를 읽고 끝에 데이터를 쓴다.[3]
그 결과 태스크의 관측 가능한 시간 거동이 물리적 실행에서 독립한다. 태스크가 자기 실행 구간 안 어느 시점에 돌든 결과는 언제나 구간의 끝에서만 나타난다. 이식성도 함께 따라온다 — 다른 코어로 옮겨도 거동이 같고, 소프트웨어가 추가되어도 통합이 가능하며, 상호운용성은 결정적 통신으로 검증된다. 의미론이 명확히 정의되어 있는 덕분에 경쟁 상태와 우선순위 역전을 다루기 위한 복잡한 동기화 장치도 필요하지 않다.
대가
대가는 지연이다. 자극이 구간 경계에 맞춰 들어오면 사슬의 종단 간 지연은 사슬에 참여한 태스크들의 주기 합과 같다. 자극이 그렇게 들어오지 않으면 사슬의 각 태스크가 자기 구간 안에서 가능한 한 일찍 실행했는데 데이터가 그 직후에 도착하는 일이 생길 수 있고, 그러면 새 데이터는 한 주기 뒤에야 소비된다. 사슬의 모든 쌍에서 같은 일이 벌어질 수 있으므로 최악의 경우 지연은 주기 합의 두 배가 된다.[3] 이 지연이 사슬 전체에서 어떤 제약과 만나는지는 종단 간 타이밍에서 다룬다.
AUTOSAR에서의 모델링
AUTOSAR 타이밍 확장은 이 구간을 이벤트 체인의 한 범주로 기술한다. 구간의 길이는 최대 지연 제약으로, 구간의 반복은 주기적 이벤트 트리거링 제약으로 표현하며, 구간 길이에는 최댓값만 쓰고 최솟값은 두지 않는다.[2]
한 구간에 여러 실행 단위가 묶일 때 그 안에서 데이터를 어떻게 주고받을지는 두 가지로 구성할 수 있다. 구간의 경계에서만 데이터를 주고받는 방식은 필요한 버퍼링을 그대로 옮기기 쉬운 대신 종단 간 지연이 주기의 배수로 길어지고, 이 방식에서는 구간 안 실행 단위의 순서가 데이터 흐름에 영향을 주지 않는다. 다른 방식은 같은 실행 순서 그룹에 속한 실행 단위들이 정해진 순서대로 실행하며 구간 안에서 직접 데이터를 주고받게 하고, 구간의 경계나 독립된 그룹 사이에서만 논리 실행 시간의 규칙을 적용한다. 후자가 기본값이다.
시스템 수준 확장
구간을 태스크 하나가 아니라 시스템 전체에 걸쳐 잡는 확장도 있다. 논리 실행 시간이 한 ECU 위 runnable의 실행 구간을 다루는 데 그친다면, 시스템 수준 확장은 세 가지를 더한다.[2]
- 기능 블록·컴포넌트·서비스의 임의의 포트 사이 데이터 흐름을 다루며, 주기보다 긴 구간 길이도 지정할 수 있다
- 동기화 정확도가 유한한 분산 클록을 명시적으로 다루어 분산 통신을 포함시킨다
- 기능 수준에서 이미 적용하고 개발 과정 전반에 걸쳐 분해해 갈 수 있다
읽기와 쓰기가 논리적으로 0의 시간에 일어난다는 가정은 여기서도 유지되며, 구현은 모델의 데이터 흐름 의미론을 보존해야 한다.