단일 스레드 EVM의 병목은 “Solidity가 느리다”가 아니라, 직렬 실행 의미론과 공유 상태에 대한 락 경합을 둘 곳이 없다는 점입니다. 멀티 엔진 병렬성은 엔지니어링 질문입니다. 충돌이 났을 때 블록 전체를 버리지 않으면서 블록의 트랜잭션을 여러 실행 컨텍스트로 어떻게 나눌 것인가. 업계의 경로: 병렬 실행으로 가는 세 가지 길. 이 글은 Bitroot 쪽 멀티 엔진 설계에 집중합니다. 이론 뼈대: OCC 입문—이 글은 데이터베이스 4단계 이야기를 다시 풀지 않습니다.
설계 목표: 병렬이되 재현 가능하게
멀티 엔진 설계가 보통 고집하는 것:
- 엔진별로 비교적 독립적인 실행 컨텍스트를 두어 전역 락을 줄입니다;
- 상태를 계정 또는 스토리지 슬롯 단위로 분할해, 엔진이 로컬 샤드를 선호하고 엔진 간 동기화를 줄이게 합니다;
- 사전 분석과 배치를 수행하는 스케줄러로, 관련 트랜잭션을 같은 엔진이나 배치에 묶어 핑퐁을 줄입니다;
- 최종 커밋이 합의 순서 아래의 직렬 실행과 동등해야 합니다(결정적 재현).
합의가 순서를 빠르게 내보내는 방법: Pipeline BFT와 실행 디커플링. 낙관적 가정과 롤백: 낙관적 병렬화. 아키텍처 지도: 병렬 EVM 아키텍처 개요.
스케줄링: 라운드 로빈처럼 뿌리는 게 아니다
순진한 라운드 로빈은 핫 컨트랙트가 나타나 엔진들이 다투기 전까지 트랜잭션을 고르게 흩뿌립니다. 더 나은 스케줄러는 다음을 추정합니다:
- 복잡도와 가스 규모(대략적으로);
- 건드릴 가능성이 있는 상태 파티션;
- 우선순위와 배치 친화도(관련 트랜잭션을 함께 묶어 엔진 간 동기화를 줄임).
스케줄링 자체에도 비용이 듭니다. 사전 분석이 너무 거칠면 잘못 묶고, 너무 세밀하면 직렬 병목이 됩니다. 흔한 타협은 “정적 휴리스틱 + 런타임 모니터링”입니다. 낙관적으로 묶고, 충돌 감지로 교정합니다. DeFi 핫스팟이 병렬성을 꿰뚫는 이유: 충돌 핫스팟과 워크로드.
상태 샤딩: 병렬 실행 다음에 오는 벽
실행이 병렬화되어도 단일 상태 트리와 단일 머신 메모리는 여전히 처리량을 제한합니다. 샤딩은 상태 공간을 나눕니다. 샤드 안에서는 병렬로, 샤드 사이에서는 명시적 메시지나 비동기 커밋으로 처리합니다. 큰 객체는 온체인 해시와 함께 오프체인 저장소에 두어 풀 노드 부담을 덜 수 있습니다. 샤딩은 공짜가 아닙니다—샤드 간 원자성과 개발자 멘탈 부하가 커집니다. 그 규칙은 프로토콜에 적어야지, 앱의 운에 맡겨서는 안 됩니다.
샤드 간 조합 가능한 DeFi는 흔히 스트레스 테스트가 됩니다. 많은 풀을 거치는 경로는 쓰기 충돌과 샤드 간 프로토콜 지연을 겹쳐 쌓습니다. 제품이 이 경계를 인정하는 방식: Bitroot 포지셔닝.
충돌 감지: 피해 범위를 줄인다
낙관적 병렬의 대가는 충돌입니다. Bitroot 자료는 3단계 감지를 강조합니다:
- 실행 전: 의존성 / 읽기-쓰기 휴리스틱으로 명백한 충돌을 같은 병렬 윈도우에 넣지 않습니다.
- 실행 중: 버전 또는 읽기/쓰기 집합 모니터링으로 무효 경로를 조기에 중단합니다.
- 실행 후: 상태 루트 일관성 검사로 놓친 충돌과 구현 버그를 잡습니다.
목표는 충돌 0이 아니라, 충돌이 났을 때 선택적으로 재실행하는 것입니다. Aptos Block-STM 스타일의 협력적 스케줄링은 구현 세부는 다르지만 같은 낙관적 계열에 속합니다—프로젝트 간 원시 테스트 TPS를 그대로 비교해서는 안 됩니다.
“엔진 수 ↔ TPS” 곡선을 읽는 법
테스트에서는 엔진을 추가할수록 처음에는 거의 선형으로 빨라지다가, 충돌률이 오르면 꺾입니다. 공개된 테스트넷 수치는 엔진이 적을 때 수천 TPS, 많을 때 최대 수만 TPS, 그리고 명시된 조건에서 1초 미만 확인을 인용했습니다—모두 하드웨어, 컨트랙트 구성, 충돌 가정에 달려 있습니다. 이는 엔지니어링 관찰이지 메인넷 SLA도, 수익 약속도 아닙니다. 유효 병렬성, 충돌률, 재실행 비중, 지연 백분위를 함께 읽는 편이 좋습니다—용어집: 성능 지표 용어집.
멀티 엔진이 기존 컨트랙트에 투명하게 남을지는 EVM 호환성(바이트코드, 프리컴파일, 툴링)에 달려 있습니다—EVM 호환성이 의미하는 것을 참고하세요. 검증인 하드웨어와 지리적 분포가 병렬 이득을 어떻게 되돌릴 수 있는지: 탈중앙화 대 성능.
합의 속도에 맞추기
멀티 엔진이 아무리 빨라도 합의 순서를 소비합니다. 실행이 블록 생성에 만성적으로 뒤처지면 미확정 상태 뷰가 쌓이고, 앱은 “블록은 빠른데 의존 트랜잭션/쿼리는 여전히 느리다”고 느낍니다. 공개 자료는 엔진 피크만이 아니라 실행 지연과 확인 백분위를 보여줘야 합니다. 파이프라인 쪽: Pipeline BFT와 실행 디커플링; 포지셔닝: Bitroot 포지셔닝.
앱 개발자에게 멀티 엔진은 투명하게 유지되어야 합니다. “병렬이라고 선언”하기 위한 Solidity 문법이 필요해서는 안 됩니다. 바뀌어야 하는 것은 상태 배치와 상호작용 패턴입니다—전역 싱글턴 카운터를 줄이고, 사용자들이 하나의 공유 슬롯에 몰려 쓰지 않게 합니다. 그렇지 않으면 추가 엔진은 재실행에만 바쁘게 돌아갑니다. 호환성: EVM 호환성이 의미하는 것; 대상 독자: 병렬 EVM을 읽어야 할 사람.
캐시, 프리페치, 엔진 간 통신 비용
엔진 수를 넘어, 계층형 캐시와 상태 프리페치가 엔진이 실제로 일하게 만들지를 좌우합니다. 로컬 샤드 적중률이 높으면 병렬성이 CPU 폭에 가까워지고, 원격 슬롯 페치가 잦으면 통신 비용에 속도 향상이 눌립니다. 가스만 보고 파티션 친화도를 보지 않는 스케줄러는 체계적으로 엔진 간 트래픽을 만듭니다.
엔진 간 읽기/쓰기 비중, 버전 충돌 건수, 샤드 간 큐 깊이를 모니터링하세요. 이런 지표가 엔진 수만 보는 것보다 실제 용량을 잘 보여줍니다. 합의 디커플링 이후, 느린 실행 따라잡기는 확인에서 상태 루트까지의 간격이 길어지는 것으로 나타납니다—사용자는 여전히 “체인이 느려졌다”고 느낍니다. 개요: 병렬 EVM 아키텍처 개요.
컨트랙트 작성자가 보게 되는 영향
멀티 엔진은 보통 Solidity 작성자에게 투명해야 합니다. 다시 쓰지 않고 배포합니다. 다만 간접적인 영향은 남습니다. 정확한 블록 내 타이밍이나 “같은 블록의 뒤 트랜잭션은 항상 앞의 쓰기를 본다”는 가정은 추측 실행 윈도우에서 더 취약합니다. 문서화되지 않은 스케줄러의 우연에 기대지 말고, 명시적 트랜잭션 경계와 이벤트에 의존하세요.
툴링은 트레이스, 가스 프로파일, 디버거에서 재실행 경로를 설명할 수 있어야 합니다. 그렇지 않으면 장애를 재구성할 수 없습니다. 독자 경로: 병렬 EVM을 읽어야 할 사람. 호환성: EVM 호환성이 의미하는 것.
멀티 엔진 설계는 충돌률 곡선이 주어졌을 때 속도 향상이 설명 가능한지, 재실행을 관찰할 수 있는지, 기존 컨트랙트 의미론이 호환되는지로 평가하세요. 이 세 가지가 데모용 멀티스레드 인터프리터가 아니라 엔지니어링된 병렬 EVM을 만듭니다.
관측성: 지표 없으면 병렬성도 없다
프로덕션 멀티 엔진에는 엔진별 활용률, 샤드 간 메시지 비율, 단계별 충돌 적중, 재실행 비중, 합의 순서에서 상태 루트까지의 시간이 필요합니다. 이런 곡선이 없으면 운영팀은 “TPS가 떨어졌다”만 보고 스케줄링인지, 핫 컨트랙트인지, 상태 I/O인지 구분하지 못합니다. 관측성을 기능의 일부로 취급하세요—출시 후 대시보드 장식이 아닙니다.
스케줄링, 샤딩, 충돌 감지는 함께 읽어야 합니다. 관측성 없는 엔진 추가는 같은 실패를 더 빠르게 반복할 뿐입니다. 충돌률 곡선 공개는 빌더와 검증인에 대한 최소한의 정직입니다.
테스트넷 수치를 공개할 때는 엔진 수, 부하 구성, 충돌률을 표시하고, 메인넷 약속이나 투자 조언이 아니라는 점을 밝히세요.
핵심 요약
멀티 엔진 병렬은 “EVM을 여러 코어에서 돌릴 수 있나”를 스케줄링, 샤딩, 충돌 제어의 문제로 바꿉니다. 충돌이 적고 분할 가능한 부하에서는 처리량을 증폭하지만, AMM 공유 풀 핫스팟에서는 엔진을 늘려도 직렬로 수렴합니다—이는 워크로드 문제이며, 마케팅 문장 하나로 없앨 수 있는 것이 아닙니다.
