CrownyJIT 5차 — 배열 원소()/설정() 네이티브 지원 (실서비스 관문 돌파)
개요
3차/4차가 남긴 "실서비스 후보 3종 전부 가속 0배" 관문의 원인은
루프 내 배열 접근
(원소()/설정())이 트랜스파일러 화이트리스트 밖 → 전량 BAIL이었다. 5차는 그 관문을 뚫었다.
배열 읽기/쓰기 opcode를 cc-경로 트랜스파일러(잎 인라인 포함)에 추가하고, 쓰기 루프의 동적
배열힙 주소를 차등게이트가 안전 검증하도록 확장했다. 공유
crownyc.c/
crownyc 무접촉(20:01),
산출물
crownyc-jit 별도. 모든 채택은 런타임 차등검증(byte-identical) 통과분만.
배열 표현 요약 (crownyc.c 정독 결과, 3줄)
- 배열 = 전역 큐브아레나
memory[] 의 base주소(int ≥10000). 레이아웃 [base+0..4095]=원소,
[base+4096]=길이. 스택에 올라가는 "핸들"=base 정수. (ARRAY_BLOCK=4097, CAP=4095)
원소/꺼내(INDEX 407)=경계검사 읽기 memory[base+i]; 설정(ARRAY_SET 415)=제자리 쓰기
후 base 반환(길이 슬롯 자동확장);
추가(APPEND 408)=제자리.
- 배열은 bump 할당(
mem_count += 4097)이라 GC 이동/재배치 없음 → base+i 절대주소가
안정적 →
rd/wr(base+i) 콜백이 메모리안전(콜백 안전경로 채택, 인라인 주소계산 불요).
지원 상태 (crownyc_jit_hot.c)
| opcode | 한선씨 | cc-루프 | 잎(leaf) | 안전장치 |
|---|
| 407 INDEX | 원소/꺼내(arr,i) | ✅ rd(base+i) | ✅ | 읽기전용=정적스냅샷 충분 |
| 406 LEN | 길이(arr) | ✅ rd(base+4096) | ✅ | 문자열핸들=게이트 MISMATCH→BAIL |
| 415 ARRAY_SET | 설정(arr,i,v) | ✅ wr(base+i,v)+base반환 | ✅ | 배열힙 영역스냅샷으로 차등검증 |
- 잎 인라인: 잎 함수 시그니처에
rd/wr 콜백을 선두인자로 전달 →
행렬원소(m,r,c)=원소(m,r*4+c)
같은 잎이 인라인됨.
arity 사전계수(cj_leaf_arity)에도 407/406/415 반영(누락 시 잎판정 전 BAIL —
실측 중 발견·수정).
- 쓰기 차등게이트: 정적 taddr(변수슬롯<10000)만으론 부족 → 쓰기루프는 배열힙
[10000..mem_count)
전 영역을 스냅샷/복원해 native·인터프리터 양쪽 배열변경을 정확 비교. 영역>2M 큐브면 BAIL(폴백).
mem_count도 게이트 전후 저장/복원(프로브 힙증가 누수 차단).
- asm 스니펫 경로는 배열 미지원(순수 스칼라 전용) → 배열루프는 자동 cc-경로.
실서비스 재실측 (best-of-3, 캐시 워밍, 단일 wall-clock)
| 워크로드 | base(no-JIT) | jit-off | jit-on | 배속 | identical | 4차(전) |
|---|
| 배열합(순수 원소/INDEX 읽기) | 4.68s | 4.77s | 0.56s | 8.4× | ✅ | — (신규 미분류 클래스) |
| 배열쓰기(설정/ARRAY_SET) | 5.17s | 5.24s | 0.81s | 6.4× | ✅ | — |
| 3D렌더러(행렬곱, 행렬원소 잎인라인) | 3.88s | 3.92s | 2.45s | 1.58× | ✅ | 0× (JIT 켜면 오히려 느림) |
| 유체시뮬(16×16×150) | 0.19s | 0.20s | 0.20s | 1.0× | ✅ | 0× |
| ARIMA(n=200,p=8) | 0.35s | 0.35s | 0.35s | 1.0× | ✅ | 0× |
- 관문 돌파: 배열접근 루프가 이전엔 100% BAIL(compiled=0) → 이제 컴파일·가속.
배열 읽기 클래스
8.4×, 쓰기 클래스
6.4×(둘 다 byte-identical). 3D렌더러(실서비스)는
compiled=1, leaves_inlined=2, native_fires=189501로
0×→1.58× (전엔 JIT가 느리게 만들던 것).
- 3D가 >2× 못 넘은 이유: 컴파일된 핫루프가 4x4 행렬의 내부 k-루프(4반복)뿐 —
루프진입당 인터프리터 1반복+디스패치 고정비가 4반복을 희석. 외곽 r/c-루프는 중첩(내부 백엣지 포함)
+행렬생성 할당루프라 단일-shape 위반으로 BAIL. (배열합/배열쓰기 마이크로벤치는 4000반복이라 관문
돌파 효과가 온전히 드러남.)
- 유체/ARIMA가 여전히 0×인 이유: 핫루프 관용구
숫자변환(문자열변환(배열[i])) = TOSTR(488)/
TOINT(486)
문자열핸들 opcode — 문자열풀 할당(480k 캡 원인)이라 JIT 화이트리스트에서 의도적 제외.
라이브러리를 직접 인덱싱으로 바꾸면 배열합처럼 가속 가능(라이브러리 수정 금지 지시로 미착수).
자기검사 캐시 (부팅 cc-spawn 고정비 절감)
- 부팅 self-test의 cc스폰(실측 ~0.39s)이 JIT-on 상시 고정비. cc툴체인 결정론적이라 최초 PASS 후
마커파일(
/tmp/.crownyjit_selftest_ok)로 cc검증 생략. 무효화=
/usr/bin/cc mtime>마커(툴체인갱신),
CROWNY_JIT_NOCACHE=1 강제재검증. 안전: 런타임 게이트가 모든 실루프를 재검증하므로 캐시오류=성능만.
- 실측: trivial 프로그램 콜드 0.90s → 캐시 0.56s(-0.34s).
회귀 (base==jitoff==jiton IDENTICAL, md5)
- 11/11 PASS: canon3M·arb2M·finance복리3M(스칼라 무영향), 배열합·배열쓰기·3D·유체·ARIMA,
crownyc_jit_hot.한선, 작업구분·브레인결재(기능 프로그램, stdin). 4모드(base/off/on/asm) 일치.
- 공유
crownyc.c(20:01:25)·crownyc(20:01:53) mtime 무손상. JIT-off crownyc-jit==공유 crownyc(드리프트0).
- 주의(실측 함정):
env CROWNY_JIT=(빈 문자열)은 getenv non-NULL → JIT 켜짐. 진짜 off는
env -u CROWNY_JIT. (초기 측정에서 "jitoff"가 실은 on이라 배속이 과소평가됐던 것을 교정.)
관련 파일 (전부 /Users/ef/CrownyOS/crownyc/)
crownyc_jit_hot.c — ★본체. 5차 추가: cc-루프/잎 트랜스파일러 407/406/415 케이스, 잎 rd/wr
선두인자 전달,
cj_leaf_arity 407/406/415 반영, 차등게이트 배열힙 영역스냅샷(
cj_has_write·
CJ_WRITE_SNAP_CAP)·mem_count 저장복원, self-test 마커캐시(
cj_selftest_cache_*).
crownyc_jit_hot.한선 — 판정 로직 한선씨 동반본. 5차 증분H~K(배열접근·쓰기게이트·잎배열·캐시 판정).
crownyc_jitmain.c/crownyc_jit_snippets.s — 5차 무수정. 빌드:
cc -O2 -o crownyc-jit crownyc_jitmain.c crownyc_jit_snippets.s -framework Security -framework CoreFoundation
crownyc.c/crownyc — 공유, 무접촉(20:01).
- 벤치/회귀 드라이버:
/tmp/JIT실적용/{배열합,배열쓰기,canon,arb,finance,3D렌더러,유체시뮬,ARIMA}.한선.
env 플래그 (5차 추가)
CROWNY_JIT_NOCACHE=1 — self-test 마커캐시 무시(항상 cc재검증).
- 기존:
CROWNY_JIT=1(켬), CROWNY_JIT_HOT=N, CROWNY_JIT_ASM/STENCIL/GATE/DUMP/TIME.
잔여 이슈 (다음 세션 인수인계)
- 3D렌더러 >2× 미달: 내부 k-루프(4반복)만 컴파일. 외곽 중첩루프 JIT(내부 백엣지 허용)·
또는 4x4 언롤 잎을 인라인하면 진입당 고정비 희석 해소 여지.
- 유체/ARIMA 0× 잔존: 핫루프의
숫자변환(문자열변환(배열[i])) 문자열핸들 관용구가 원인.
라이브러리를 직접 인덱싱(원소() 직접 정수)으로 바꾸면 배열합급 가속(라이브러리 수정 금지로 보류).
- 쓰기루프 성능: 원소/설정이 매회 rd/wr 콜백(blr) — 접촉 배열base를 callee-saved 레지스터에
호이스팅하면 추가 가속(4차 남은과제 1과 동일 축). 현재도 6.4×라 우선순위 낮음.
- 배열힙 영역스냅샷은 O(mem_count) — 큰 힙 프로그램의 쓰기루프는 상한(2M)에서 BAIL. 접촉주소
write-log 방식으로 정밀화하면 큰 힙에서도 쓰기가속 가능(단 인터프리터 쓰기 포착 필요).