aboutsummaryrefslogtreecommitdiffstats
path: root/docs/research/049-idle-app-work-slots.md
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-24 17:14:54 +0100
committereunhhu <[email protected]>2026-09-24 17:14:54 +0100
commitb1ce1927022d374198441afafeb27199fc8a052a (patch)
tree6021f175f4c67ed03b44240eaa2f90d846f12f6f /docs/research/049-idle-app-work-slots.md
parentd34f9426d5317a1948f12f229439946728bc342a (diff)
downloadpure-b1ce1927022d374198441afafeb27199fc8a052a.tar.gz
pure-b1ce1927022d374198441afafeb27199fc8a052a.zip
Establish native micro runtime checkpoint
Diffstat (limited to 'docs/research/049-idle-app-work-slots.md')
-rw-r--r--docs/research/049-idle-app-work-slots.md101
1 files changed, 101 insertions, 0 deletions
diff --git a/docs/research/049-idle-app-work-slots.md b/docs/research/049-idle-app-work-slots.md
new file mode 100644
index 0000000..27c22d7
--- /dev/null
+++ b/docs/research/049-idle-app-work-slots.md
@@ -0,0 +1,101 @@
+# 049 — 앱이 쉴 때 작업 슬롯도 비운다
+
+Pure 실행 영역은 호출자가 제공한 작업 슬롯을 보유한다. 기존 네이티브 작성 앱은
+입력 한 건에는 슬롯 하나, 저장·복원의 `READ → WRITE` 전달에는 둘이 필요해서
+**모든 유휴 인스턴스에 `PureWork[2]` 448 B를 계속 예약**했다. 이전에 계산 정의를
+공유해 scalar 인스턴스를 280 B까지 줄인 [028](028-shared-fixed-program.md) 이후에는
+이 448 B가 독립 앱의 반복 비용에서 더 큰 부분이었다.
+
+코어에 `pure_runtime_bind()`를 추가했다. 영역은 작업 슬롯 없이 시작할 수 있고,
+호스트가 진행 중인 호출에 필요한 슬롯을 제공한다. 네이티브 앱은 입력에 1개,
+저장·복원에 2개를 **소유 스레드의 호출 스택에만** 두고, 결과·대여가 모두 회수된
+뒤 분리한다. 슬롯을 바꿔도 영역의 예산·누적 계수·티켓 세대는 유지된다. 진행 중
+작업, 완료를 보유한 티켓, 다른 영역이 고정한 본문이 있으면 분리를 거절한다.
+[코어의 실제 대여·세대 검사](../../prototypes/connections/test-runtime.c)는 수신 영역이
+원본 본문을 소비할 때까지 분리가 실패하고, 회수 뒤 성공하며, 오래된 티켓이 새
+슬롯을 가리키지 못함을 확인한다. 선택형 장시간 비동기 HTTP 호스트는 계속 고정
+슬롯을 사용한다. 이 변경은 동기 앱의 호출 수명에만 적용한다.
+
+[전체 앱 메모리 A/B 원자료](../../prototypes/workbench/results/2026-09-24-idle-work-binding/app-memory.json)는
+같은 준비된 `routed-layout.pure`와 같은 scalar 아카이브로 각각 **독립 앱
+1,000개**를 초기화한다. 각 앱이 코어를 통해 입력을 처리하고 서로 다른 문서를
+저장하며, 다섯 앱을 다시 복원한다. 실행마다 접수와 회수가 3,010건씩 일치하고
+저장 파일을 확인한다. 이전 앱 소스는 [동결된 작성 호스트
+소스](../../prototypes/workbench/results/2026-09-24-native-desktop/sources/native/app.c)와
+[헤더](../../prototypes/workbench/results/2026-09-24-native-desktop/sources/native/app.h)를
+그대로 사용했다. 비교 하네스는 현재 소스에서 두 실행물을 다시 빌드한다.
+Linux에서 Zig 0.15.2가 있다면 저장소 루트에서
+`python3 prototypes/workbench/manage.py native prototypes/workbench/examples/routed-layout.pure`
+후 `(cd prototypes/workbench && python3 native/check_app_memory.py)`로 재현한다.
+
+| Linux AArch64 / GCC 14, 같은 실제 앱 1,000개 | 이전 고정 슬롯 | 호출 중 대여 |
+|---|---:|---:|
+| 앱 컨트롤러 / 인스턴스 | 928 B | 480 B |
+| scalar 상태 / 인스턴스 | 280 B | 280 B |
+| 초기화 후 RSS 증가, 3회 중앙값 | 1,264 KiB | 832 KiB |
+| 저장 후 RSS 증가, 3회 중앙값 | 1,328 KiB | 896 KiB |
+| A/B 하네스 실행물 `text` | 35,698 B | 35,962 B |
+
+컨트롤러에서는 인스턴스당 448 B, 실제 프로세스 RSS 증가량에서는 이 작업의
+**432 KiB**가 줄었다. A/B 둘 다 변경 후의 같은 코어를 링크했고, 앱 호스트만
+다른 실행물의 `text` 차이는 264 B다. 공통 코어의
+[최신 크기 검사](../../prototypes/connections/results/2026-09-24-idle-work-binding/core.json)는
+`text` 5,932→6,076 B, 영역 200 B, 작업 슬롯 224 B다. 코어의 기존
+6,144 B 상한은 올리지 않았다. 코드 증분을 숨기지 않으면서 유휴 앱 1,000개의
+반복 예약을 줄인 결과다.
+
+메모리가 사라진 것은 아니다. [GCC 정적 스택 추정](../../prototypes/workbench/results/2026-09-24-idle-work-binding/stack-baseline.su)을
+[새 실행](../../prototypes/workbench/results/2026-09-24-idle-work-binding/stack-elastic.su)과
+비교하면 `pure_native_app_action`은 208→432 B, 저장·복원 공통 `transfer`는
+288→736 B다. 각각 224 B와 448 B를 **호출 중에** 스택으로 옮겼다. 이 수치는
+함수 자신의 정적 스택 추정이며 호출 체인 전체의 피크가 아니다. 한 소유 스레드가
+동기 호출을 진행하는 현재 앱 계약에 맞는 선택이고, 작업을 반환 뒤에도 보유하는
+호스트에는 이 배치를 적용하지 않는다.
+
+## 선택한 배포 묶음의 비용
+
+변경 후 기존 `--strip-debug` 방식의 CLI+TUI 압축 묶음은
+[35,847 B](../../prototypes/connections/results/2026-09-24-idle-work-binding/precompact-budget-failure.txt)가 되어
+35,840 B 상한을 7 B 넘었다. 상한을 올리는 대신 고정 실행 묶음에서는 실행에
+필요 없는 ELF 심볼도 제거하도록 했다. 디버깅용 빌드와 소스 작성 묶음은 그대로
+두며, `text` 코드 섹션이나 프로세스 RSS가 작아졌다고 주장하지 않는다.
+패키지 매니페스트에는 실행마다 달라지는 RSS 표본을 넣지 않고, 크기 상한과
+실행물 식별자만 남겼다. 실제 RSS 표본은 별도 검사 JSON에 보관한다.
+동일한 의존성 검사를 거쳐 새 위치에서 실제 실행한 결과는 다음과 같다.
+
+| 고정 정의 선택 | 압축 묶음 | 회귀 상한 | 이동 후 동작 |
+|---|---:|---:|---|
+| [CLI](../../prototypes/connections/results/2026-09-24-idle-work-binding/cli.tar.gz) | 12,987 B | 16,384 B | [검증](../../prototypes/connections/results/2026-09-24-idle-work-binding/cli-check.json) |
+| [CLI+HTTP](../../prototypes/connections/results/2026-09-24-idle-work-binding/cli-http.tar.gz) | 28,719 B | 34,816 B | [검증](../../prototypes/connections/results/2026-09-24-idle-work-binding/cli-http-check.json) |
+| [CLI+TUI](../../prototypes/connections/results/2026-09-24-idle-work-binding/cli-tui.tar.gz) | 31,726 B | 35,840 B | [검증](../../prototypes/connections/results/2026-09-24-idle-work-binding/cli-tui-check.json) |
+| [CLI+HTTP+TUI](../../prototypes/connections/results/2026-09-24-idle-work-binding/cli-http-tui.tar.gz) | 47,419 B | 54,272 B | [검증](../../prototypes/connections/results/2026-09-24-idle-work-binding/cli-http-tui-check.json) |
+
+소스 `.pure`를 묶어 실행 시 정의를 읽는 [작성 CLI 묶음](../../prototypes/connections/results/2026-09-24-idle-work-binding/source-cli.tar.gz)은
+22,595 B이고 [이동 후 편집·복원](../../prototypes/connections/results/2026-09-24-idle-work-binding/source-cli-check.json)을
+확인했다. 고정 정의 묶음과 기능·크기를 동등한 것으로 취급하지 않는다.
+앞선 [047의 CLI+TUI 묶음](047-bounded-native-document-browser.md)은 35,642 B였다.
+현재 묶음은 코어 기능이 늘어난 뒤에도 3,916 B 작다. 이 차이는 패키지에서
+사용하지 않는 심볼을 제거한 효과다. 작성 CLI와 고정 정의 네 선택을 각각 다시 빌드한
+[아카이브 바이트 해시](../../prototypes/connections/results/2026-09-24-idle-work-binding/package-reproducibility.json)도
+일치했다. 프로그램 실행 메모리 절감은 위 1,000개 앱 A/B에서 별도로 확인했다.
+
+[기본 릴리스 검사](../../prototypes/connections/results/2026-09-24-idle-work-binding/release.log),
+[선택형 비동기 코어](../../prototypes/connections/results/2026-09-24-idle-work-binding/async-core.json),
+[실제 HTTP 쓰기 중 읽기](../../prototypes/connections/results/2026-09-24-idle-work-binding/async-gated.json),
+[1,024개 문서 서비스](../../prototypes/connections/results/2026-09-24-idle-work-binding/service-scale.json),
+[PTY 문서 편집기](../../prototypes/connections/results/2026-09-24-idle-work-binding/tui.json),
+[인증 문서 피어](../../prototypes/connections/results/2026-09-24-idle-work-binding/document-peer.json)가
+통과했다. 작성 앱의 [독립 상태·충돌·정의 교체
+검사](../../prototypes/workbench/results/2026-09-24-idle-work-binding/native-unit.json),
+[C 코드 ASan·UBSan](../../prototypes/workbench/results/2026-09-24-idle-work-binding/native-sanitized.json),
+[인증 scalar 피어](../../prototypes/workbench/results/2026-09-24-idle-work-binding/scalar-peer.json)도
+통과했다. 공통 코어의 [ASan·UBSan 검사](../../prototypes/connections/results/2026-09-24-idle-work-binding/runtime-sanitized.json)는
+대여 중인 슬롯과 오래된 티켓을 포함한다.
+
+이 A/B는 같은 프로세스의 1,000개 **동기 네이티브 앱**에 대한 메모리 결과다.
+실제 네트워크 서비스 1,000명 처리량, 불신 코드 격리, macOS RSS를 증명하지 않는다.
+Zig 0.15.2 실행 파일이 현재 환경에 없어서 scalar 아카이브를 다시 빌드하지는
+못했다. 준비된 정의를 현재 소스로 재생성해 기존 아카이브 프로필과 일치함을
+검사했고 A/B 모두 동일한 아카이브를 링크했다. 코어·C 호스트는 현재 소스에서
+재빌드했다. 다음 연구에서는 유휴 영역 자체의 200 B와 일반 I/O 계약을 함께
+검토해야 하며, 슬롯 절감을 이유로 수명·예산의 귀속을 약화해서는 안 된다.