한국정보기술진흥원
한국정보기술신문
thumbnail

정보기술 · 인공지능 ·

앤트로픽의 AI 제작 C 컴파일러, 정확성은 높지만 속도는 GCC의 1/737 수준...리눅스 커널 링킹도 실패

발행일
읽는 시간4분 47초

클로드 오퍼스 4.6이 작성한 CCC, 2,844개 파일 컴파일 성공했지만 레지스터 할당 문제로 실행 속도 치명적

[한국정보기술신문] 앤트로픽이 인공지능 클로드를 이용해 완전히 자동으로 제작한 C 컴파일러 CCC가 공개되었으나, 독립 개발자의 벤치마크 결과 실용성에는 심각한 한계가 있는 것으로 드러났다. 코드의 정확성은 확보했지만 실행 속도가 업계 표준인 GCC의 수백 분의 1에 불과한 것으로 나타났다.

지난 2월 7일 앤트로픽은 공식 블로그를 통해 클로드 오퍼스 4.6 모델이 100% 작성한 C 컴파일러 CCC를 공개했다. 이 프로젝트에서 사람은 오직 테스트 케이스 작성을 통한 가이드 역할만 수행했으며, 프론트엔드, SSA 기반 IR, 최적화기, 코드 생성기, 어셈블러, 링커, DWARF 디버그 정보 생성 등 모든 구성 요소가 AI에 의해 구현되었다. CCC는 Rust로 작성되었으며 x86-64, i686, AArch64, RISC-V 64 등 4개 아키텍처를 지원한다.

앤트로픽 측은 CCC가 리눅스 커널을 컴파일할 수 있다고 주장했으나, 독립 개발자 하샤누의 검증 결과 이는 부분적 사실로 확인되었다. CCC는 리눅스 6.9 커널의 2,844개 C 소스 파일을 컴파일러 오류 없이 모두 처리하는 데 성공했지만, 링커 단계에서 40,784개의 정의되지 않은 참조 오류를 발생시키며 최종 바이너리 생성에 실패했다.

컴파일은 성공, 링킹은 실패

하샤누는 2개의 데비안 기반 가상머신에서 각각 GCC 14.2.0과 CCC를 이용해 리눅스 커널 6.9를 컴파일하는 벤치마크를 수행했다. 각 VM은 6개 vCPU, 16GB RAM, 100GB NVMe 디스크로 구성되었다. CCC는 gcc_m16 기능을 활성화하여 빌드되었는데, 이는 CCC의 i686 백엔드가 32KB 실모드 제한을 초과하는 코드를 생성하기 때문에 16비트 실모드 부트 코드 처리를 GCC에 위임하기 위한 것이다.

컴파일 단계에서 CCC는 42.5분 만에 모든 C 파일 처리를 완료했으며, 이는 GCC의 73.2분보다 빠른 수치다. 그러나 이는 최적화 작업을 수행하지 않았기 때문으로 분석된다. 실제로 GCC의 O0 최적화 수준과 비교하면 CCC가 약 25% 더 느린 것으로 나타났다.

링커 오류의 원인은 CCC가 커널의 점프 레이블과 심볼 테이블 엔트리에 대해 잘못된 재배치 정보를 생성했기 때문이다. 구체적으로 __jump_table 재배치와 __ksymtab 참조에서 문제가 발생했다. 이는 C 언어 컴파일 자체의 버그가 아니라 링커가 볼 수 있는 재배치 및 심볼 생성의 버그로, 컴파일러 개발에서 링커 부분이 가장 어려운 이유를 보여주는 사례라고 할 수 있다.

SQLite 벤치마크, 정확성은 확보했지만 속도는 치명적

하샤누는 SQLite 3.46 아말감 파일을 이용한 실행 성능 벤치마크도 수행했다. SQLite는 단일 C 파일로 배포되며 표준 C로 작성되어 컴파일러 테스트에 적합하다는 장점이 있다.

컴파일 시간 측면에서 CCC는 87초가 걸렸으며, 이는 GCC O0 모드의 64.6초보다 1.3배 느린 수치다. 그러나 바이너리 크기는 4.27MB로 GCC O0의 1.55MB보다 2.75배 컸다. 주목할 점은 CCC의 O0과 O2 플래그가 바이트 단위로 동일한 바이너리를 생성한다는 것이다. CCC는 15개의 SSA 최적화 패스를 가지고 있지만 모든 최적화 레벨에서 동일하게 실행되며, O 플래그는 실질적으로 무시된다.

실행 시간에서는 더욱 심각한 차이가 드러났다. GCC O0으로 컴파일된 SQLite가 10.3초에 벤치마크를 완료한 반면, CCC로 컴파일된 버전은 2시간 6분이 소요되어 737배 느렸다. GCC O2와 비교하면 1,242배의 격차가 발생했다.

더욱 주목할 만한 점은 쿼리 유형에 따른 성능 차이다. 단순한 INSERT나 DROP TABLE 작업은 1.1-1.7배 정도의 차이에 그쳤지만, 중첩 루프를 포함하는 복잡한 작업에서는 격차가 기하급수적으로 벌어졌다. NOT IN 서브쿼리는 158,129배, 크로스 테이블 조인과 GROUP BY를 결합한 쿼리는 26,235배 느렸다.

레지스터 스필링이 주범

성능 저하의 핵심 원인은 과도한 레지스터 스필링으로 분석되었다. 최신 CPU는 제한된 수의 고속 저장 공간인 레지스터를 가지고 있으며, 우수한 컴파일러는 자주 사용되는 변수를 이 레지스터에 유지하려 한다. 변수가 레지스터보다 많으면 컴파일러는 이를 훨씬 느린 스택 메모리로 옮기는데, 이를 레지스터 스필링이라고 한다.

SQLite의 핵심 실행 엔진인 sqlite3VdbeExec 함수는 100개 이상의 지역 변수와 대규모 switch 문을 가진 단일 함수다. CCC는 효율적인 레지스터 할당 알고리즘이 없어 거의 모든 변수를 스택으로 스필링한다.

디스어셈블리 분석 결과, GCC O0이 383줄의 어셈블리를 생성한 반면 CCC는 1,189줄을 생성했다. CCC는 rax 레지스터를 단순한 셔틀로 사용하여 스택 위치 간에 값을 이동시키는 방식을 취하며, -0x2ae8(11,000바이트 깊이)에 이르는 깊은 스택 오프셋을 사용했다. 모든 연산이 스택에서 rax로, 다시 rax에서 스택으로 이동하는 패턴을 보였다.

32개 지역 변수와 switch 문을 사용하는 마이크로 벤치마크에서 CCC는 8.604초가 걸려 GCC O0의 2.026초보다 4.2배 느렸다. 이 비율이 100개 이상의 변수와 200개 이상의 case를 가진 sqlite3VdbeExec에서 복합적으로 작용하여 100배 이상의 격차로 이어진 것으로 분석된다.

코드 블로트와 디버깅 불가

코드 크기 증가도 심각한 문제다. CCC로 컴파일된 SQLite 바이너리는 4.27MB로 GCC O0의 1.55MB보다 2.75배 크다. 디스어셈블리 라인 수도 838,359줄로 GCC의 301,424줄보다 2.78배 많다. 이러한 코드 블로트는 더 많은 인스트럭션 캐시 미스를 야기하며, 레지스터 스필링 페널티를 더욱 악화시킨다.

또한 CCC로 컴파일된 바이너리는 내부 함수 심볼이 없다. nm 명령어는 0개의 심볼을 보고하고, readelf는 GCC의 1,500개 이상 함수 대비 90개의 PLT 스텁만 표시한다. 이는 프로파일링과 디버깅을 사실상 불가능하게 만든다.

GDB 스택 트레이스 분석 결과, CCC로 컴파일된 SQLite 실행 중 프레임 포인터가 손상된 것으로 나타났다. 유효하지 않은 반환 주소와 스택이 아닌 힙 주소가 스택 트레이스에 나타나는 등 CCC가 적절한 프레임 포인터 체인을 생성하지 않는 것으로 확인되었다.

헬로 월드도 컴파일 안 돼

앤트로픽이 CCC를 공개한 지 몇 시간 만에 깃허브 이슈 1번이 등록되었다. 내용은 헬로 월드가 컴파일되지 않는다는 것이었다. 리드미에 있는 예제조차 새로 설치한 우분투에서 작동하지 않았다.

문제는 CCC의 전처리기가 stddef.h와 stdarg.h에 대한 올바른 시스템 인클루드 경로를 검색하지 않는다는 것이었다. 이 헤더 파일들은 C 라이브러리가 아닌 컴파일러에서 제공된다. 이 이슈는 288개의 좋아요 반응과 200개 이상의 댓글을 받았으며, 사람들이 claude 계정을 태그하며 버그 수정을 요청하는 전설적인 깃허브 스레드가 되었다. 누군가는 어셈블리 출력이 학부생의 컴파일러 과제를 연상시킨다고 평했다. 이 이슈는 현재도 열려 있는 상태다.

AI 컴파일러의 가능성과 한계

그럼에도 불구하고 CCC는 주목할 만한 성과다. AI가 완전히 제작한 작동하는 C 컴파일러로서 리눅스 커널의 2,844개 파일을 단 하나의 오류 없이 컴파일할 수 있었다. SQLite로 검증한 결과 모든 쿼리가 올바른 결과를 반환했고 모든 크래시 테스트를 통과했다. 기능적 정확성은 확보된 것이다.

하샤누는 앤트로픽이 목표로 한 클로드가 복잡한 소프트웨어를 구축할 수 있음을 입증한다는 측면에서 CCC는 진정한 성공이라고 평가했다. 그러나 실제로 효율적으로 실행할 소프트웨어를 컴파일하려는 사람에게는 GCC나 Clang 같은 프로덕션 컴파일러가 유일한 선택지로 남아 있다고 덧붙였다.

앤트로픽 측은 이번 프로젝트가 AI의 소프트웨어 개발 능력을 보여주는 실험적 시도라고 설명하고 있다. 컴파일러 개발은 40년 가까이 수천 명의 개발자가 참여해온 GCC의 역사가 보여주듯 방대한 엔지니어링 노하우가 축적된 분야다. 레지스터 할당, 함수 인라이닝, 루프 언롤링, 벡터화, 데드 코드 제거, 상수 전파 등의 최적화 패스만 해도 수년간의 박사 수준 연구를 대표한다.

CCC 프로젝트의 소스코드와 하샤누의 벤치마크 스크립트는 깃허브에 공개되어 있다. 벤치마크는 두 개의 독립된 물리 노드에서 실행되었으며, 동일한 하드웨어 사양과 소스코드를 사용하여 공정한 비교를 추구했다. 컴파일러 메모리 사용량에서도 CCC는 1,616MB를 사용하여 GCC의 272MB보다 5.9배 많은 것으로 나타났다.

한국정보기술신문 인공지능분과 전호재 기자 news@kitpa.org