← 목록
기타 2026-07-12 6KB 읽기 6분

벡터 직결 10ms 파이프라인 완성 — 회귀 원인 규명 + 픽셀 삭제 + p50 4.4ms 달성 (2026-07-12)

개요

요청: "파이선 없게 하고 JIT 최적화를 했었는데 왜 다시 꼬이고 회귀되었을까? VM 작업 학습해서 총 10ms 미만으로 개선. 원리적으로 루프를 돌 일이 없는 구조인데 대충 연결한 것 해결." + 중간 확정 지시: "픽셀을 쓰라고 한 적 없다 — 벡터로 구현하면 0.01ms도 안 들 것" → 픽셀 단계 삭제, 벡터 display list 직결로 설계 전환.

수행: 조사 워크플로(5축, 5에이전트) → 설계 계약 고정 → 구현 워크플로(A한선씨+B ObjC 병렬 → C통합E2E → D적대검증, 4에이전트).

결과: 상호작용 1회 p50 4.39ms (목표 10ms의 절반 이하) — 양측 독립 확인

측정방법
GUI E2E p50 (통합검증 C)4.39ms (p95 5.03)실기동 GUI, 프로덕션 함수 경유(sendVectorEvent→소켓→parseVectorCmd→drawRect), N=30
GUI E2E p50 (적대검증 D 독립)4.478ms동일 하네스 독립 재실행 N=42
소켓 단독3.4~4.0ms별도 도구 2회 N=20
⚠ 꼬리 지연 (D)p95 7.16ms, 2/42건(4.8%)이 10ms 초과(max 12.5ms)공유 머신 고부하(load 7.2, crownyc 다수 상주) 기인 — p50 기준 통과, C의 p95=5.03 보고는 과소대표였음
개선 폭: 110~134ms → 4.4ms (약 25~30배). python(51ms)·PPM FB_SAVE(31~42ms)·프로세스 스폰 3~4회/이벤트 전부 소멸.

새 아키텍처

이벤트(키/클릭) → ObjC 인프로세스 BSD소켓 → 앱상주서버.한선(VM 상주: 상태+cmd 벡터 생성)
  → 응답 payload로 cmd 직접 수신 → CrownyAppView drawRect CG 벡터 드로우
     (RECT/ROUND/SHADOW→CGPath, TEXT→CIF v4 벡터글리프 CGPath 캐시, HIT→네이티브 히트테스트)

산출물

  • src/앱상주서버.한선 신규 1,327줄 — 멀티서비스(터미널·계산기) 상주 서버. 기존 3 verb 100% 호환 + 신규 벡터| verb(응답에 cmd 직접). 요청마다 메모리마커/맵힙마커 복원. STRICT 경고 0, 결정론 재컴파일 확인. learn 등재: 앱상주서버_벡터직결_멀티서비스.
  • native/crowny-browser.m — CIF v4→CGPath 글리프 캐시(cbDrawVectorText), display list 파서+drawRect 벡터 분기(_hasDisplayList — PPM 경로와 상호배타), termSrv→appSrv 일반화, 5개 이벤트 지점 벡터 우선+스폰 폴백, routeCrownyAppURL 라우팅 단일화(두 진입점 createTabWithURL·navigateActiveTabTo 모두 — 기존엔 한쪽만 리다이렉트된 반쪽 적용), --selftest-vector 신규. 두 빌드구성 컴파일 exit0·신규 경고 0. crownyonly 빌드 WebKit 링크 0 확인.
  • 3곳 바이너리 mv 원자 배치, sha256 일치(99c4a09…). 실행 중 인스턴스 없었음(간섭 0).
  • 회귀 0: selftest-inputv2 19/19, 웹탭, 콜드스폰 폴백(포트 봉쇄 실증), 미전환 앱(메모) PPM 경로.
  • 문서: 벡터직결-B-ObjC.md, 벡터직결-C-통합검증.md(에이전트 작성), 본 문서(종합).

회귀 원인 (첫 질문 답 — 타임라인 조사 확정)

  1. python = 06-29 "단기 브리지 D" 명시 채택 후 A(순수 한선씨) 미완으로 정본화. 훅이 .py 미감지. 44ms 실체 = 인터프리터 기동 47% + 죽은 import(zipfile 등) 27% + 유효 연산 1~2ms(3~4%)뿐.
  2. JIT = 회귀 아님, 애초 범위 밖. 07-02 기획부터 "브라우저=I/O바운드, JIT 0%" 스코프 아웃, 07-10 재확인. 이번 실측: GUI opcode 루프는 JIT 무조건 BAIL.
  3. 07-12 09:45 리다이렉트 = 근거 문서 없는 "더미" 오판정 + 반쪽 적용(createTabWithURL만 막고 navigateActiveTabTo는 구 경로 직행). 같은 날 00:43 문서가 실동작을 실측했는데 참조 없이 폐기 — "대충 연결"의 실체.
  4. 근본 메커니즘 = 문서·메모리의 강제력 0. 검증된 투자(상주VM 프로토타입 2.7배 등)가 세션 간 참조·반박 없이 뒤집힘. → 이번엔 리다이렉트 자리에 결정기록 주석 삽입 + 신규 함정 6종을 가드레일 템플릿(훅 주입 대상)에 등재.

조사에서 확정된 결정적 사실 (설계 근거)

  • FB_SAVE(PPM) = 픽셀당 개별 fwrite → 1280×800 = 31~42ms. python을 없애도 픽셀 경로로는 10ms 불가였음 — 벡터 직결이 유일해(사장님 판단 실측 입증).
  • dirty-rect RGB 드로우 <2µs, 벡터글리프 웜 16~20µs, VM 인터프리터 10ms에 16~40만 opcode 여유 — VM 자체는 전 구간 무죄.
  • 신규 VM 함정 6종 실측 → 가드레일 템플릿 + 메모리(feedback_vm_렌더함정_*) 등재: 배열리터럴 256 상한, 글자()=O(len)/전순회 O(n²), GV_CACHE 512 자기수축, 지우기 c27평면만, END 프레이밍 스톨, FB_SAVE 선형.

잔여 이슈

  1. 좌표 기반 실클릭 히트테스트 E2E 미확정 — 액션명 직접 경로(hit:)는 N=42 검증 완료. 실좌표 합성클릭(CROWNY_AUTOCLICK)은 하네스 자체의 사이드바 오프셋 버그로 11/11 미스(프로덕션 mouseDown은 OS 실좌표 사용이라 별개 가능성 높음). 후속: 하네스 좌표 보정 후 재검증.
  2. p95 꼬리(2/42건 >10ms) — 머신 부하 기인. 상주 서버 우선순위/QoS 검토 여지.
  3. 한글 자모 조합(IME) 경로는 벡터 프로토콜 미포함(기존 경로 유지, 의도적 범위 제외).
  4. 터미널 스크롤백 빈영역 클릭이 구 히트맵 파일 의존(근사 동작, 기능마비 아님).
  5. 미전환 앱 8종(메모·시계·날씨 등)은 PPM 경로 유지 — 앱상주서버 서비스 테이블에 순차 이식하면 python/PPM 완전 퇴역 가능.
  6. 새 바이너리는 배치 완료 — 다음 CrownyAI.app 실행부터 벡터 파이프라인 활성.

관련 파일

  • src/앱상주서버.한선 (신규 정본) · native/crowny-browser.m (벡터 렌더러+라우팅)
  • 계약 SSOT: 스크래치패드 벡터직결-계약.md (프로토콜 명세 — 후속 앱 이식 시 참조)
  • 조사·구현 워크플로: wf_55037bfb-38f(조사 5축), wf_d75fe734-7ba(구현 4단)
  • 선행 점검: 2026-07-12-크라우니AI-속도우위-전체점검.md