From b1ce1927022d374198441afafeb27199fc8a052a Mon Sep 17 00:00:00 2001 From: eunhhu Date: Thu, 24 Sep 2026 17:14:54 +0100 Subject: Establish native micro runtime checkpoint --- docs/research/006-problem-landscape.md | 263 +++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 docs/research/006-problem-landscape.md (limited to 'docs/research/006-problem-landscape.md') diff --git a/docs/research/006-problem-landscape.md b/docs/research/006-problem-landscape.md new file mode 100644 index 0000000..cbfd6b7 --- /dev/null +++ b/docs/research/006-problem-landscape.md @@ -0,0 +1,263 @@ +# Pure 연구 보고서 006: 먼저 풀 문제를 고르기 + +작성일·자료 확인일: 2026-09-22 +상태: **1차 문헌 조사와 실험 전략. 새 성능 측정이나 독창성 입증은 없음.** + +## 이번 판단 + +언어·플랫폼별 실제 문제를 먼저 조사하고 Pure의 전략을 정하는 방향이 맞다. +좋은 문제는 개선의 실용적 가치를 결정하고, 실제 성능은 알고리즘·구현·작업 조건으로 검증해야 한다. +각 언어의 약점 목록에서 출발하되, 최종 연구 단위는 **작업 → 비용 발생 원인 → 기존 최선의 해결책 → 남은 비용**으로 잡는다. + +이 조사에서는 서비스·개발 도구의 운영 보고와 공식 구현 문서에서 10개 후보를 검토했다. +여러 사례에는 이미 좋은 해결책이 있다. 따라서 지금 정한 ABI·버퍼 풀·연산 규칙은 +문제에 맞춰 수정할 후보 설계다. 먼저 구현하고 그 구조가 유리한 문제를 뒤에서 고르는 순서를 피한다. + +첫 후보는 **여러 처리 단계에 걸친 버퍼 수명과 메모리 예산**이다. +사용 경험으로는 큰 파일이나 연속 데이터를 다룰 때 메모리가 예측 가능하고, +출력이 느려져도 조작·취소가 정상적으로 처리되는 것으로 나타나야 한다. +이번에는 사용자가 조작할 새 구현체가 없다. 기존 제작 화면도 이 가설을 검증하지 않는다. + +## 조사 범위와 해석 한계 + +- Discord·Instagram·VS Code 자료는 실제 시스템을 개선한 당사자의 역사적 보고다. 당시 원인이 지금도 그대로 남았다는 증거는 아니다. +- Sonic·Node.js·.NET·Rust·Java·SwiftUI·Metal·Arrow 자료는 공식 기능·구현 설명이다. 그 자체를 대규모 운영 장애나 Pure의 성능 증거로 취급하지 않는다. +- 전체 언어·플랫폼을 망라한 조사나 체계적 논문 검토가 아니다. 동적 문서의 현재 내용을 확인했지만 재현할 버전·커밋은 아직 고정하지 않았다. +- 아래의 ‘Pure 가설’과 우선순위는 자료를 바탕으로 한 우리의 추론이다. 원문 저자들이 Pure의 필요성을 주장한 것이 아니다. + +## 10개 후보와 현재 해법 + +### P01. Go: 큰 캐시의 메모리와 지연 + +Discord는 2020년 Read States 서비스에서 큰 캐시의 GC 비용과 주기적인 지연을 보고했다. +캐시를 줄이면 데이터베이스 접근이 증가하는 상충 관계가 있었다. Rust 전환에는 자료구조와 +복사 경로 등의 변경도 포함되어 언어만 바꾼 통제 실험으로 읽을 수 없다. +[Discord 운영 보고](https://discord.com/blog/why-discord-is-switching-from-go-to-rust). + +**기존 해법:** 캐시 정책·자료 배치·할당 감소·GC 설정과 메모리 제한을 먼저 검토한다. +Go의 공식 GC 안내도 CPU와 메모리 사이의 비용 관계를 설명한다. 이 안내는 Go 1.19를 기준으로 +설명한다고 명시하므로 재현 시 선택한 버전에서 다시 확인한다. +[Go GC guide](https://go.dev/doc/gc-guide). + +**Pure 가설:** 수명이 다른 데이터를 구분하면 회수 비용과 메모리 유지량을 줄일 수 있는가? +동등하게 최적화한 Go 및 C/Rust 구현이 비교 대상이다. GC가 없는 구현의 이득만 확인되면 +Pure 고유의 기여는 아직 없다. 캐시 적중률·DB 작업량도 같아야 한다. **우선순위: 보조 후보.** + +### P02. Python: 읽기 위주 데이터도 프로세스마다 복제되는 비용 + +Instagram의 pre-fork 환경에서는 참조 횟수 등 객체 관리 정보의 쓰기가 공유 페이지의 +copy-on-write를 유발했다. Meta는 immortal objects로 이 문제를 줄이는 작업을 보고했고, +PEP 683은 Python 3.12를 대상으로 채택되었다. 모든 사용자 객체가 자동으로 이 혜택을 +받는다는 의미는 아니다. +[Meta, 2023](https://engineering.fb.com/2023/08/15/developer-tools/immortal-objects-for-python-instagram-meta/), +[PEP 683](https://peps.python.org/pep-0683/). + +**Pure 가설:** 읽기 전용 본문과 변경되는 관리 정보를 분리할 가치가 남아 있는가? +기존 Python 개선과 명시적 공유 메모리가 비교 대상이다. 프로세스별 RSS를 단순 합산하지 않고 +공유·전용 페이지를 구분한다. 이 문제의 pre-fork 전제를 모바일·브라우저에 일반화하지 않는다. +**우선순위: 해당 실행 환경을 선택할 때 재검토.** + +### P03. Node.js / .NET: 느린 소비자와 버퍼 누적 + +Node.js는 streams의 역압력으로 생산 속도를 제어한다. .NET Pipelines도 풀링된 버퍼와 +writer 중단·재개 임계값을 제공하며, 소비·검사 위치를 잘못 전달하면 메모리 문제나 정체가 +생길 수 있음을 문서화한다. 역압력과 버퍼 재사용은 이미 제공되는 기능이다. +[Node.js streams](https://nodejs.org/learn/modules/backpressuring-in-streams), +[System.IO.Pipelines](https://learn.microsoft.com/en-us/dotnet/standard/io/pipelines). + +**Pure 가설:** 변환·분기·캐시·완료 대기를 합친 예산을 공유하면, 각 단계가 개별적으로 +제한을 두는 구현보다 같은 처리량·지연 조건에서 메모리를 덜 유지하는가? +올바른 역압력과 전역 예산을 추가한 기존 구현까지 비교해야 한다. +느린 소비자에서 입력을 무조건 버려 얻은 수치는 동일 기능의 성능 개선이 아니다. +**우선순위: 첫 연구, P04와 함께 검토.** + +### P04. ByteDance Sonic: 복사를 생략한 결과 원본 전체가 살아남는 비용 + +Sonic은 디코딩한 문자열이 원본 JSON을 참조하면서, 작은 결과를 보관해도 원본 버퍼가 +유지될 수 있음을 설명한다. `CopyString` 및 검색 결과의 `CopyReturn` 같은 선택지도 제공한다. +복사량과 장기 메모리 유지량 사이에 상충 관계가 있다는 구체적인 사례다. +[Sonic 공식 저장소](https://github.com/bytedance/sonic#tips). + +**Pure 가설:** 원본 크기·남기는 범위·메모리 압력을 이용해 공유와 복사를 선택하면 +일괄 정책보다 유리한가? 항상 복사, 항상 공유, 단순 크기 임계값, 기존 라이브러리 설정이 +비교 대상이다. 미래의 실제 보관 시간을 미리 아는 정책을 실용 구현처럼 비교하지 않는다. +**우선순위: 첫 연구. 기존 옵션보다 남는 이득이 있는지부터 확인.** + +### P05. Rust: 특수화의 실행 성능과 빌드 비용 + +rustc는 제네릭의 구체 타입별 코드를 생성하는 monomorphization을 사용한다. +공식 가이드는 실행 성능의 이점과 컴파일 시간·바이너리 크기 비용을 함께 설명한다. +이것만으로 Rust 컴파일러 전체의 크기나 어떤 앱의 메모리 사용 원인을 설명할 수는 없다. +[Rust Compiler Development Guide](https://rustc-dev-guide.rust-lang.org/backend/monomorph.html). + +**Pure 가설:** 공통 실행과 제한적 특수화를 조합해 원하는 실행 성능에서 빌드 비용을 +통제할 수 있는가? 컴파일러 배포 크기, 빌드 시간·최대 RAM, 산출물 크기, 실행 RAM을 +별도로 기록한다. 동등한 기능을 가진 비교가 필요하며 현재 작은 DSL의 크기를 범용 언어와 +직접 비교하지 않는다. **우선순위: 모든 단계의 관리 지표. 첫 대표 문제로는 보류.** + +### P06. JVM: 이미 해결된 제약을 연구 대상으로 고르는 위험 + +JDK 24는 `synchronized` 안에서 대기하는 virtual thread가 carrier thread를 붙잡는 +제약을 완화하는 JEP 491을 반영했다. 이전 버전의 대표 문제를 최신 Java 전체의 +한계로 삼으면 출발점부터 비교가 틀어진다. 모든 native/FFI 상황의 제약이 없어졌다는 뜻은 아니다. +[Oracle JDK 24 변경 사항](https://docs.oracle.com/en/java/javase/24/migrate/significant-changes-jdk-24.html). + +**Pure 판단:** 이 과거 제약은 첫 연구 후보에서 제외한다. 실제 작업의 남은 대기 비용이 +확인되면 지원 중인 대상 JDK와 비교한다. 작은 스케줄러를 만드는 것만으로 우월성을 주장하지 않는다. + +### P07. TypeScript / VS Code: 작은 변경에 큰 문서를 다시 처리하는 비용 + +VS Code의 2021년 괄호 색상 개선은 확장 API의 제약을 넘어서 토큰 정보와 증분 자료구조를 +활용했다. 보고된 큰 개선은 특정 괄호 갱신 작업에 대한 것으로, 앱 전체나 언어 간 속도 비율이 아니다. +기존 확장 호스트의 격리는 무거운 작업 중 UI 반응성을 지키는 역할도 했다. +[VS Code 개발팀 보고](https://code.visualstudio.com/blogs/2021/09/29/bracket-pair-colorization). + +**Pure 가설:** 작은 수정이 유발하는 재계산·데이터 이동 범위를 예산 안에서 제한할 수 있는가? +비교 대상도 증분 알고리즘을 사용해야 한다. 의존성 추적 메모리와 초기 구축·대규모 수정 비용을 +포함한다. **우선순위: 두 번째 연구 후보, 실제 문서·데이터 편집 기능과 연결.** + +### P08. SwiftUI: 상태 의존성과 갱신 범위 + +Apple은 SwiftUI 성능 분석에서 의존성, 뷰의 identity, 비용이 큰 갱신 작업을 다룬다. +SwiftUI 자체가 의존성을 추적하므로 변경된 부분만 처리한다는 발상만으로 차별화되지는 않는다. +[Apple WWDC23: Demystify SwiftUI performance](https://developer.apple.com/videos/play/wwdc2023/10160/). + +**Pure 가설:** 상태·입력·출력의 연결 정보로 불필요한 갱신을 줄이면서 추적 메모리도 +제한할 수 있는가? 적절히 상태를 분리한 기존 구현과 비교한다. 렌더러 차이와 상태 처리 차이를 +분리하고 동일한 화면·상호작용을 유지한다. **우선순위: P07과 묶어 후속 검토.** + +### P09. Apple Metal: 통합 메모리에서도 남는 자원 수명과 동기화 + +Apple GPU는 시스템 메모리를 공유하지만 자원 접근 방식에 따라 shared/private/memoryless를 +선택한다. shared 자원도 CPU·GPU 접근 순서를 동기화해야 한다. +[Apple 저장 모드 안내](https://developer.apple.com/documentation/metal/choosing-a-resource-storage-mode-for-apple-gpus), +[shared 접근 계약](https://developer.apple.com/documentation/metal/mtlstoragemode/shared). + +**Pure 가설:** 입력에서 GPU 완료까지 자원 수명을 연결해 임시 자원과 대기를 줄일 수 있는가? +잘 구성한 Metal 직접 구현이 비교 대상이다. 동시에 진행하는 프레임 수와 출력 품질을 맞추고 +CPU·GPU 대기 및 메모리를 함께 측정한다. 현재 Linux 측정은 사용자의 Apple Silicon에서 +실행한 증거가 아니다. **우선순위: 실제 Mac 프로파일을 확보한 뒤.** + +### P10. C/C++ 및 다중 언어 경계: 이미 있는 무복사 ABI + +Apache Arrow C Data Interface는 같은 프로세스 안에서 언어·런타임 간 columnar 데이터를 +공유할 수 있는 작은 C 인터페이스와 해제 계약을 제공한다. 프로세스 간 전송이나 영속 저장 형식은 +그 인터페이스의 범위가 아니다. +[Arrow C Data Interface](https://arrow.apache.org/docs/format/CDataInterface.html). + +**Pure 가설:** 기존 인터페이스로 표현되지 않는 비동기 수명·예산 관리가 필요한가? +Arrow에 맞는 데이터는 이를 활용하는 방안을 먼저 비교한다. 자체 ABI의 필요성은 함수 호출, +버전 처리, 소유권, 호환 비용까지 보여야 한다. **우선순위: 재사용·연동 기준.** + +## 첫 연구 질문 + +> 여러 단계가 입력을 나눠 읽고 일부 결과를 오래 보관하는 작업에서, +> 전체 예산과 원본 버퍼 수명을 함께 관리하면 기존의 잘 구성한 구현보다 +> 같은 처리량·지연 조건에서 메모리 유지량을 줄일 수 있는가? + +**귀무가설 H0:** 기존의 제한된 큐, 메모리 풀, 단순 복사 정책을 조합하면 Pure 후보와 +동등하거나 더 좋은 비용을 얻는다. 이 경우 공통 라이브러리나 어댑터 수준으로 해결하고 +그 문제를 이유로 새 언어·ABI·스케줄러를 확대하지 않는다. + +**대안 가설 H1:** 단계 간 예산과 수명 정보를 공유하는 정책이, 입력 분포가 달라져도 +단순 정책 대비 유리한 메모리·처리량·지연 조합을 만든다. 그 이득이 관리 정보·계측·호스트 +비용을 포함해 남고 다른 작업에도 적용되는지 확인한다. 이 가설은 아직 검증되지 않았다. + +현재 초안의 버퍼 전체 단위 대여와 완료 회수 시점도 수정 대상이다. +큰 원본의 작은 구간 때문에 전체 할당이 유지되거나 완료 회수가 밀리면 오히려 비용이 커질 수 있다. +복사를 줄이는 지표 하나만 목표로 삼지 않는다. + +## 재현할 작업과 비교 순서 + +첫 작업 후보는 **큰 로그·구조화 데이터에서 필드를 추출하고, 일부 결과를 보관하면서 +느린 출력으로 내보내는 CLI**다. 이는 연구용 작업 제안이며 제품 범위를 확정한 것은 아니다. +후속으로 압축 입력과 문서 탐색 화면을 연결할 수 있지만 첫 비교에 모두 넣지 않는다. + +1. **기존 구현에서 비용 재현.** 단일 프로세스의 제한된 처리 흐름으로 시작한다. + 입력 크기, 레코드 크기 분포, 보관 비율, 소비자 속도, 분기 수를 독립적으로 바꾼다. + 합성 데이터는 생성 규칙·seed를 공개하고 실제 운영 추적이라고 부르지 않는다. +2. **비교 구현 개선.** 항상 복사·공유·단순 임계값 정책을 비교하고, + 올바른 역압력·전역 예산·버퍼 풀까지 적용한다. 튜닝에 쓴 입력과 평가 입력을 분리한다. +3. **남은 비용 분석.** 원본 유지·대기열·파싱·할당·I/O 중 비용이 어디에 있는지 확인한다. + Pure가 건드릴 수 있는 경로의 비중이 작으면 우선순위를 낮춘다. +4. **최소한의 Pure 정책 비교.** 같은 언어·파서·I/O 경로에서 정책만 바꿔 원인을 분리한다. + 외부 언어·플랫폼 비교는 별도 실험으로 보고한다. 파서 교체로 얻은 이득을 수명 정책의 이득으로 돌리지 않는다. +5. **실제 제작 경험.** 가치가 확인된 작업을 사용자가 빈 작업물에서 작성·수정하게 한다. + 새 필터·출력·보관 정책을 추가할 때마다 실행기 코드를 고쳐야 하는지 기록한다. + +큰 파일 하나만으로 대규모 서비스의 특성을 대체할 수 없다. 데이터/메모리 비율, +동시 작업 수, 보관 시간 분포, 부하 급증, 느린 소비자의 분포를 드러내야 한다. +네트워크를 붙일 때는 도착 부하와 큐 대기 시간을 기록하고, 느려진 만큼 요청 발생도 늦어져 +지연이 작아 보이는 측정 오류를 피한다. 분산 저장소·핫키·질의 설계의 비용은 별도로 분석한다. + +## 측정과 탈락 기준 + +| 축 | 반드시 포함할 것 | +|---|---| +| 정확성 | 출력 내용·순서, 잘린 입력, 실패·취소, 완료 후 자원 반환 | +| 메모리 | 예약·사용·유지 바이트, 큐·풀·관리 정보, 라이브러리 내부 할당, 프로세스 메모리 | +| 수명 | 원본 할당별 마지막 참조 시점, 유지 바이트의 시간 적분(byte·seconds), 최고 유지량 | +| 복사 | 경로별 복사 바이트, 공유로 연장된 수명, 계측 밖 경로 | +| 처리 | 완료한 유효 작업량, 처리량, 큐 대기를 포함한 지연 분포, 거절·손실·취소 수 | +| 구축 비용 | 도구 버전, 빌드 시간·최대 RAM, 실행 파일·모듈·의존성 크기 | +| 측정 조건 | OS·CPU·RAM, 빌드 옵션·커밋, 입력·설정, 워밍업, 반복 분산, 계측 자체 비용 | + +공유 원본은 할당별로 한 번만 센다. 풀 예약량·RSS·GPU 통계를 무조건 더하지 않는다. +관리하는 버퍼 예산과 전체 프로세스 메모리 상한을 구분한다. 취소가 접수됐다는 이유로 +아직 접근 중인 메모리를 반납해 성능을 높이는 구현은 실패다. + +실험 전에 작업의 메모리 한도와 필요한 지연·처리량을 정한다. 숫자는 실제 사용 조건에서 정하고 +유리한 결과를 본 뒤 고르지 않는다. 같은 조건에서 반복 측정의 변동보다 확실한 차이가 있는지, +다른 입력에서는 어떤 손해가 생기는지 함께 보고한다. + +다음 중 하나면 가설을 기각하거나 범위를 줄인다. + +- 단순한 기존 정책을 튜닝하면 차이가 사라진다. +- 관리 정보·라이브러리·호스트 비용을 포함하면 이득이 사라진다. +- 메모리를 줄인 대가로 필요한 처리량·지연·정확성을 만족하지 못한다. +- 특정 입력에만 유리하며 평가에 쓰지 않은 입력에서 재현되지 않는다. +- 새 런타임 없이 작은 라이브러리 변경으로 같은 결과를 얻는다. 이 경우 그 변경 자체의 가치를 평가한다. + +## 연구 기여를 판단하기 위한 다음 문헌 단계 + +운영 사례는 문제의 존재를 보여주지만 새로운 해법의 독창성을 증명하지 않는다. +첫 문제의 잔여 비용이 확인되면 다음 주제의 원 논문·공개 구현과 비교표를 만든다. + +- 영역 기반 메모리 관리와 소유권/대여: 회수 단위와 수명 표현의 기존 해법. +- 스트리밍 실행기의 admission control·역압력·메모리 예약: 전역 예산의 기존 해법. +- 공유 버퍼의 보관·복사 정책: 미래 수명을 모르는 온라인 결정과 관리 비용. +- 증분 계산·질의 처리: 입력 변화에 비례한 작업량과 추적 상태 비용. + +각 연구의 전제, 보장, 비용, 실패 조건, 재현 가능 구현을 기록한다. +현재는 이 논문 검토를 완료하지 않았으므로 새로운 원리나 세계 최초라는 표현을 사용하지 않는다. + +## 기존 계획에 대한 결정 + +[005의 계약 초안](005-foundation-contract.md)은 유지하되, 구현 우선순위 앞에 +**기존 해법의 재현과 남은 비용 확인**을 둔다. 버퍼 풀·자체 ABI·커널 우회 중 무엇이 필요한지는 +그 결과에서 결정한다. 컴파일러 크기 관리는 병행하는 측정 항목이다. + +다음 산출물은 새 문법 데모가 아니라 첫 후보의 **재현 가능한 비교 구현과 비용 보고서**다. +첫 후보에서 차별화가 확인되지 않으면 그 결과를 남기고 P07/P08 또는 실제 Mac 작업을 검토한다. +압축·암호화·문서·미디어·OS의 장기 목표는 유지하지만, 한 실험의 결과를 모든 분야의 성능으로 확대하지 않는다. + +2026-09-22 진행 기록: [007의 첫 비교 실험](007-buffer-retention-results.md)에서 단일 FIFO의 +원본 유지 비용을 재현했다. 기존 복사·선별 읽기 정책으로 개선됐으며 Pure 고유의 이점은 확인하지 못했다. +007의 범위에는 여러 소비자와 실제 파서의 잔여 비용 검증이 포함되지 않았다. + +추가 진행: [008](008-json-fanout-results.md)에서 실제 JSON 파서와 다중 소비자의 제한된 작업을 +검증했다. 기존 정책 대비 고유한 이점을 확인하지 못해 P03/P04는 기반 품질 과제로 유지하고, +다음 대표 연구 후보는 P07/P08의 증분 편집·갱신 비용으로 옮긴다. 실제 운영 작업 전체에 대한 결론은 아니다. + +작업 범위 보완: 공유·복사 정책 비교는 여기서 종료하고 원자료를 보존한다. +P07/P08는 아직 구현 대상으로 확정하지 않는다. 먼저 기존 문헌·공개 구현에서 +구체적인 편집 작업의 비용과 기존 해법의 한계를 확인한다. **기존 해법 채택으로 +충분한지, Pure의 실행 방식 변경이 필요한지**를 가르는 근거만 조사한다. +작은 변경을 전체 재계산과 비교해 빠르다는 사실을 재현하는 데 그치면 탈락이다. +남은 비용과 최소 확인 방법을 특정할 수 있을 때만 비교 구현으로 넘어간다. +세부 작업 기준은 [협업 방식](000-working-method.md)을 따른다. + +자체 구현 진행: P07/P08의 일반적인 증분 처리 벤치마크 대신, 초기 연구 질문 중 +추적 기록의 제거를 [작은 실행 코어](../../prototypes/forgetful-core/README.md)로 +구체화했다. 변경 기록이 부족할 때의 재계산, 조건부 의존성의 보존, 작업 한도 내 +거절을 확인했다. 이는 자체 실행 계약 구현이며 신규성·성능 우위의 결론은 아니다. -- cgit v1.2.3