aboutsummaryrefslogtreecommitdiffstats
path: root/docs/design
diff options
context:
space:
mode:
Diffstat (limited to 'docs/design')
-rw-r--r--docs/design/029-past-one-node.md61
1 files changed, 47 insertions, 14 deletions
diff --git a/docs/design/029-past-one-node.md b/docs/design/029-past-one-node.md
index f36c913..cef1a7b 100644
--- a/docs/design/029-past-one-node.md
+++ b/docs/design/029-past-one-node.md
@@ -4,7 +4,9 @@
원리 둘과 열린 질문 하나, 그리고 원리마다 그것을 깰 수 있는 실험 하나만 적는다.
**원리 1은 UAX #14에서 깨졌다(2026-10-19, 045).** 두 실험 모두 막대에 못 미쳤다. (가) 2.19배(막대 4배), (나) 1.31배(막대
-3배). 아래 "깨는 실험의 결과"에 무엇을 시험했고 무엇은 시험하지 않았는지 적는다. 원리 2는 아직 시험하지 않았다.
+3배). 아래 "깨는 실험의 결과"에 무엇을 시험했고 무엇은 시험하지 않았는지 적는다. 깨진 것은 "실행기의 몸을 이어 붙인다"는
+길이다. 표현까지 증명에서 내보내는 것은 range() 하나에서 C의 1.75배였다(잰 점 하나, 앱 전체가 아니다). 원리 2는 아직 시험하지
+않았다.
## 쉬운 말로
@@ -13,7 +15,8 @@ pure link는 전송 세션이 들고 있던 것(순번, 확인, 다시 보내기
같은 질문을 남은 결함에 던진다. **어느 두 계층이 같은 정보를 들고 있는가, 그리고 어느 쪽을 지울 수 있는가.**
- **원리 1.** 검증기가 증명한 것을 실행기 셋이 다시 알아내거나 버린다. 증명을 버리지 않으면 실행기 셋이 사라진다.
- **깨졌다(045).** 해석은 절벽의 작은 몫이었다.
+ **이어 붙이는 길은 깨졌다(045).** range()에서 절벽은 수와 리스트의 표현(10.9배), 메모리의 칸과 부름(3.29배), 분배(1.78배)의
+ 곱이었다.
- **원리 2.** 복제 프로토콜이 들고 다닐 것을 저장소의 커밋과 링크가 이미 들고 있다. 복제 계층이 사라진다.
## 원리 1. 증명이 곧 컴파일러다
@@ -96,18 +99,48 @@ C의 속도로 컴파일하기 쉬운 쪽**이어야 한다. 61–183배의 절�
| 부름(들어가기, 나오기, 리스트 바꿔 끼우기) | 2,847 | 7.1% | 5 |
| malloc과 free | 1,609 | 4.0% | 3 |
| 사건, 고리, 가리지 못한 것 | 2,273 | 5.6% | 4 |
- - **어느 계층도 절벽의 대부분을 들지 않는다.** 일반적인 계층 셋(해석, 리스트의 표현, 수의 표현)이 저마다 지워져도 1.4–1.5배다.
- 절벽은 그 곱이다.
- - range()의 이분 탐색 하나가 코드 포인트당 14,489개, 36%다(변형 v0r). 반복은 11.4번, 한 번에 약 1,270개다. 그 안에서 `//`가
- 186(`fmod`로 정확히 내린다), 저장 리스트의 읽기가 240이다. Vega의 C는 종류를 두 단계 표에서 한 번에 읽는다. 비교는 그대로
- 서지만, 저장 리스트 읽기의 몫은 앱이 고른 알고리즘 때문에 크다.
-- **깨진 후보 하나(셈으로, 코드 전에).** "let 리스트는 프레임에서 나고 죽으며 별칭이 없는데, 런타임은 그것을 판이 있는 상태로
- 만들어 부를 때마다 바꿔 끼운다. 프레임이 이미 든 수명을 상태 계층이 다시 든다." 지울 수 있는 몫을 모두 더해도(리스트 짓기 6,953,
- let 리스트의 읽기 약 2,500, 부름 약 2,500, 메모리 약 1,500) 약 13,000, 32%다. 값 없이 지워도 1.5배다. 절벽을 들지 못하니 깨졌다.
-- **막대의 셈.** 실행된 명령은 549.9개, C는 기계 명령 220개다. 명령 하나가 기계 명령 하나여도 C의 2.5배다. (가)의 지움 뒤 251개를
- 하나에 3개쯤으로 내면 약 750, C의 3.4배다. 그래서 UAX #14에서 "C의 1–3배"는 실행만으로 닿지 않는다. 명령의 수도 줄어야 하고,
- 550 가운데 269.5가 Vega의 C가 하지 않는 이분 탐색이다(변형 v0r에서 셈, `2026-10-19-ops-v0r.txt`). 이분 탐색의 명령 하나는 기계
- 명령 54개, 나머지 앱의 명령 하나는 92개다.
+ - 처음 이 자리에 "어느 계층도 절벽의 대부분을 들지 않는다, 저마다 지워져도 1.4–1.5배"라고 적었다. 그것은 실행기 안의 몫이지
+ 인자가 아니었다. 다른 계층을 그대로 두고 한 계층의 몫을 잰 것이다. 아래 range()의 사슬이 보이듯 계층은 곱해지고, 한 계층의
+ 인자는 다른 계층이 지워진 뒤에야 드러난다.
+ - range()의 이분 탐색 하나가 코드 포인트당 14,489개, 36%다(변형 v0r). 실행된 명령으로는 549.9 가운데 269.5다
+ (`2026-10-19-ops-v0r.txt`). 반복은 11.4번이다. Vega의 C는 종류를 두 단계 표에서 한 번에 읽는다. 그래서 저장 리스트 읽기의
+ 몫은 앱이 고른 알고리즘 때문에 크다.
+- **range()를 손으로 내보낸 사슬(`range.c`, 2026-10-19).** 내보내기가 쓸 코드를 손으로 쓰고, 증명이 허락할 수 있는 것을 하나씩
+ 지웠다. 모든 방식의 답이 61,285개 코드 포인트 모두에서 실행기와 이어 붙인 판의 답과 같다.
+ | 방식 | 남은 것 | 기계 명령/점 | 사이클/점 | 반복 한 번 |
+ |---|---|---|---|---|
+ | 실행기 | 분배, 메모리의 칸, 부름의 기계, 아래 전부 | 14,488 | 5,508 | |
+ | 이어 붙임 | 메모리의 칸, 부름의 기계, 아래 전부 | 8,144 | 3,209 | |
+ | exact | 레지스터와 맨 부름. double, `fmod`의 `//`, 유한·정수 검사, 트리 읽기, 예산 | 2,474 | 1,315 | 217 |
+ | integer | exact에서 수를 정수로 | 1,587 | 875 | 139 |
+ | flat | exact에서 `start`를 평평한 열에서 | 1,083 | 633 | 95 |
+ | both | 정수와 평평한 열. 경계 검사와 예산은 남는다 | 226 | 125 | 19.8 |
+ | C | 같은 이분 탐색, 검사도 예산도 없이 | 129 | 93 | 11.3 |
+ - 인자(기계 명령): 분배 1.78배, 메모리의 칸과 부름의 기계 3.29배, 수와 리스트의 표현 10.9배, 남은 경계 검사와 예산이 C의 1.75배.
+ 사이클로는 1.72, 2.44, 10.5배, C의 1.36배다.
+ - **미리 정한 막대(C 반복의 3배, 34)로: exact 217은 못 미치고, both 19.8은 지난다.** 판정은 미리 적은 대로다. range()에서 절벽은
+ 분배가 아니라 수와 리스트의 표현, 그리고 메모리의 칸과 부름에 있다.
+ - 확인한 전제 셋.
+ - "리스트가 바뀌지 않음": 증명되어 있다. 검증기는 fn마다 그것이 바꾸는 리스트의 집합(`function_changes`)을 증명하고, range()는
+ 아무것도 바꾸지 않는다.
+ - "정수 인덱스임": **증명되어 있지 않다.** low와 high는 `number`이고, INDEX_AT이 정수인지를 실행 중에 검사한다. aup는 그것을 알
+ 수 있다(0, `.count`, 정수끼리의 `//`). 하지만 지금은 aup도 검증기도 그 사실을 적지 않는다. 증명에 새로 넣어야 할 사실이고, 그것
+ 하나로 1.56배다.
+ - "함수 지역 수명": range()는 제 리스트가 없어서 이 실험이 시험하지 않는다.
+ - 묶인 것과 단서.
+ - 이어 붙임 → exact의 3.29배는 메모리의 칸과 부름의 기계를 함께 지운다. 둘을 가르지 않았다. 부름 하나의 값(단위 1,375)으로 어림하면
+ 5,670 가운데 약 1,400이 부름이다. 어림이다.
+ - 평평한 열은 잰 구간 밖에서 지었다. 증명이 허락하는 것은 "부름 안에서 바뀌지 않음"이다. 돌아가는 시스템에서는 그 값이 바뀔 때로
+ 옮겨 간다. `ranges`(한 번 싣는다)에는 거의 없지만, 사건마다 바뀌는 리스트에는 재지 않았다. 트리의 잎은 이미 열이다(090).
+ 반복당 122개가 내려가기인지 칸의 일반 경로인지는 가르지 않았다.
+ - 앱의 36%만이다. decide, let 리스트, `Text`의 복사는 이 사슬로 보이지 않았다.
+- **고친 것: let 리스트 후보.** 처음 이 자리에 "셈으로 깨졌다(13,000, 32%, 1.5배)"라고 적었다. 그것도 실행기 안의 몫이었다. 그래서
+ 인자로서는 재지 않은 채로 남는다. 시험은 몫이 아니라 사슬이다.
+- **고친 것: 막대의 셈.** "명령 하나가 기계 명령 하나여도 C의 2.5배"라고 적었다. 명령의 수가 바닥이라고 본 것인데, range()의 both는
+ 실행된 명령 269.5개를 기계 명령 226개로 한다(하나에 0.84). 레지스터 아래에서 옮김과 상수가 사라진다. 그 셈은 틀렸다.
+- **원리 1이 지금 말하는 것.** 시험한 길(실행기의 몸을 이어 붙이기)은 죽었다(앱 1.43배, range() 1.78배). 시험하지 않았던 주장(표현까지
+ 포함해 증명에서 내보내기)에 잰 점이 하나 생겼다. range()에서 C의 1.75배다. 정수임은 증명에 새로 넣어야 하고, 경계 검사와 예산이
+ 남는다. 새 원리가 아니라, 미리 정한 막대 아래의 점 하나다.
## 원리 2. 커밋이 곧 복제본이다