[번역] 웹어셈블리의 현재 위치와 미래

이 글은 모질라 Hacks의 웹어셈블리 시리즈 중 마지막 글인 Where is WebAssembly now and what’s next?의 번역글이다. 전 시리즈에 걸쳐 웹어셈블리 뿐만 아니라 JIT나 어셈블리 등에 대해서도 체계적으로 잘 설명하고 있고, 카툰까지 곁들여서 이해하기도 쉽다.

총 6부로 되어 있으며, 원작자의 허가를 얻어 전체 시리즈를 모두 번역했으니 처음부터 차례대로 모두 읽어보길 권한다.

  1. 카툰으로 소개하는 웹어셈블리
  2. 저스트-인-타임(JIT) 컴파일러 집중 코스
  3. 어셈블리 집중 코스
  4. 웹어셈블리 모듈의 생성과 동작
  5. 웹어셈블리는 왜 빠를까?
  6. 웹어셈블리의 현재 위치와 미래 (현재글)

 

2월 28일, 4개의 주요 브라우저들은 웹어셈블리의 MVP가 완료되었다는 합의에 이르렀다고 발표했다. 이는 브라우저들이 탑재를 시작할 수 있는 최초의 안정적인 버전을 제공한다.

logo_party01-500x169.png

이는 브라우저가 탑재할 수 있는 안정적인 코어를 제공한다. 이 코어는 커뮤니티 그룹이 계획하고 있는 모든 기능을 포함하고 있지는 않지만, 웹어셈블리를 빠르고 사용가능하도록 만들기에는 충분하다.

이것을 이용하면, 개발자들은 웹어셈블리 코드를 탑재할 수 있다. 이전 버전의 브라우저를 위해서 개발자들은 asm.js 버전의 코드를 내려보낼 수 있다. asm.js는 자바스크립트의 서브셋이기 때문에, 모든 JS 엔진이 이를 실행할 수 있다. Emscripten을 이용하면 동일한 앱을 웹어셈블리와 asm.js로 컴파일 할 수 있다.

최초 버전임에도 불구하고, 웹어셈블리는 빠를 것이다. 하지만 수정과 새로운 기능들이 더해지면, 앞으로는 더 빨라질 것이다.

브라우저에서 웹어셈블리 성능 향상시키기

브라우저들이 엔진상의 웹어셈블리 지원을 개선할수록 속도는 더 빨리질 것이다. 브라우저 벤더들이 이러한 이슈들을 위해 독자적으로 노력하고 있다.

JS와 웹어셈블리 간의 더 빠른 함수 호출

현재 JS 코드에서 웹어셈블리 함수를 호출하는 것은 필요 이상으로 느리다. 이는 트램폴린(trampolining)”이라는 것이 필요하기 때문이다. JIT는 웹어셈블리를 직접 어떻게 다루어야 할 지 모르기 때문에, 그 역할을 하는 것에게 웹어셈블리를 전달해야 한다. 이것은 엔진 내부에 있는 코드중 느린 부분인데, 최적화된 웹어셈블리 코드를 실행하기 위한 셋업 작업을 한다.

06-02-trampoline01-500x399.png

이 작업은 JIT가 웹어셈블리를 직접 어떻게 다룰지 아는 경우에 비해 100배 이상 느릴 수 있다.

만약 당신이 웹어셈블리 모듈에게 하나의 큰 작업만 넘겨준다면 이러한 오버헤드를 눈치채지 못할 수도 있다. 하지만 만약 웹어셈블리와 JS간에 빈번한 교류가 발생한다면(작은 여러개의 작업을 이용해서) 이 오버헤드가 두드러질 것이다.

더 빠른 로딩 시간

JIT는 더 빠른 로딩 시간과 더 빠른 실행 시간 사이의 트레이드-오프를 관리해야 한다. 만약 당신이 미리 컴파일하고 최적화하는 데에 더 많은 시간을 사용한다면, 실행 시간은 빨라질 수 있겠지만, 초기 구동 시간은 느려지게 된다.

코드가 한 번 실행된 후에 더 이상 끊김이 없도록 보장하기 위해 미리 컴파일을 하는 것과 대부분의 코드는 충분히 자주 실행되지 않기 때문에 최적화하는 것이 큰 의미가 없다는 사실 사이의 균형을 유지하기 위해 많은 작업들이 진행되고 있다.

웹어셈블리는 어떤 타입들이 사용될 지 추측할 필요가 없기 때문에, 실행 시점에 어떤 타입들이 사용되는지를 엔진이 모니터링할 필요가 없다. 이는 엔진에게 더 많은 선택지를 주는데, 예를 들면 컴파일을 실행과 병행해서 진행할 수도 있다.

게다가, 최근에 추가된 자바스크립트 API는 스트림을 이용해서 웹어셈블리를 컴파일할 수 있도록 해 준다. 즉, 바이트를 다운로드 받는 동안에 엔진이 컴파일을 시작할 수 있게 된다.

파이어폭스에서 우리는 두가지의 컴파일러 시스템을 작업하고 있다. 하나는 미리 실행되어 꽤 괜찮은 수준까지 코드를 최적화한다. 코드가 실행되는 동안에는 다른 컴파일러가 백그라운드에서 완벽하게 최적화를 한다. 완전히 최적화된 코드가 준비되면 기존 코드와 교체되어 들어간다.

MVP 이후 스펙에 추가될 기능들

웹어셈블리의 목표 중 하나는 모든 것을 한 번에 디자인하는 것보다는, 작은 조각으로 나누어 구체화하면서 계속해서 테스트하는 것이다.

즉, 기대되는 기능들이 있긴 하지만, 이들이 미리 100% 완벽하게 구체화되지는 않았다는 의미이다. 이들은 모든 브라우저 벤더들이 참여해서 스펙화하는 과정을 거쳐야만 할 것이다.

이 기능들은 미래 기능(future features)이라 불린다. 몇 가지만 살펴보겠다. 

DOM 직접 다루기

현재로선 DOM과 상호작용할 수 있는 방법이 존재하지 않는다. 즉, 웹어셈블리에서는  element.innerHTML과 같은 식으로 노드를 갱신할 수 없다는 의미이다. 

대신에, JS를 통해서 값을 설정하도록 해야 한다. 이 말은 자바스크립트 호출자(caller)에게 값을 다시 전달한다는 의미가 될 수도 있다. 아니면, 웹어셈블리 내부에서 자바스크립트 함수를 호출한다는 의미가 될 수도 있다. (자바스크립트와 웹어셈블리 함수 모두 웹어셈블리 모듈에서 임포트해서 사용할 수 있다)

06-03-dom01-500x418.png

어느 방법이든, 자바스크립트를 통하는 것은 직접 접근하는 것보다는 느릴 것이다. 일부 웹어셈블리 어플리케이션들은 이 문제가 해결될 때까지 기다려야 할 수도 있을 것이다.

공유 메모리의 동시성

코드의 속도를 향상시키는 한가지 방법은 코드의 다른 부분들이 동시에 병렬적으로 실행될 수 있게 만드는 것이다. 하지만 이 방법은 가끔 역효과를 일으키는데, 쓰레드간의 커뮤니케이션으로 인한 오버헤드가 원래 하려는 작업보다 더 많은 시간이 걸릴 수 있기 때문이다.

하지만 쓰레드간에 메모리를 공유할 수 있다면 이러한 오버헤드를 줄일 수 있다. 이를 위해 웹어셈블리는 자바스크립트에서 새롭게 추가된 SharedArrayBuffer를 사용할 것이다. 이 기능이 브라우저에서 제공되기 시작하면 웹어셈블리가 어떻게 이를 다룰지에 대해 작업 그룹이 스펙을 구체화할 수 있을 것이다.

SIMD

만약 웹어셈블리에 대한 다른 글을 읽거나 발표를 본 적이 있다면, 아마도 SIMD 지원에 대해서 들어보았을 것이다. SIMD는 단일 명령, 다중 데이터 (single instruction, multiple data)의 약자이다. 이는 병렬 실행을 위한 또다른 방법이다.

SIMD는 여러 수들로 이루어진 벡터와 같은 대량의 데이터 구조를 취해서, 각기 다른 부분에 동일한 명령을 동시에 적용할 수 있도록 해 준다. 이 방식으로 게임이나 VR에 필요한 복잡한 연산에 대한 성능을 급격하게 향상시킬 수 있다.

보통의 웹 앱 개발자들에게는 이것이 크게 중요하지 않을 것이다. 하지만 게임과 같은 멀티미디어 관련 개발자들에게 이 기능은 아주 중요하다.

예외 처리

C++과 같은 언어들의 많은 코드 베이스는 예외(exception)를 사용한다. 하지만 예외는 웹어셈블리의 일부로써 정의되어 있지 않다.

만약 Emscripten을 이용해 코드를 컴파일한다면, 컴파일러 최적화 단계에서 예외 처리를 에뮬레이트 해 줄 것이다. 하지만 꽤나 느리기 때문에, DISABLE_EXCEPTION_CATCHING 플래그를 이용해서 이 기능을 끄고 싶을 수도 있을 것이다. 

웹어셈블리에서 직접 예외 처리를 지원하게 된다면 이러한 에뮬레이션은 더이상 필요없을 것이다.

그 외에 개발자 편의를 위한 개선들

몇가지 미래 기능들은 성능에 영향을 끼치지는 않지만, 개발자들이 웹어셈블리를 다루기 쉽게 만들어 줄 것이다.

  • 일급 소스 레벨 개발자 도구. 현재 브라우저에서 웹어셈블리를 디버깅 하는 것은 순수 어셈블리를 디버깅하는 것이나 마찬가지일 것이다. 하지만 아주 소수의 개발자들만이 머릿속에서 자신의 코드를 어셈블리로 맵핑할 수 있다. 우리는 개발자들이 소스코드를 디버깅하는 것을 지원하는 도구를 어떻게 개선할 수 있을지 조사하고 있다.
  • 가비지 컬렉션. 만약 타입을 미리 정의할 수 있다면, 그 코드를 웹어셈블리로 변환할 수도 있어야만 한다. 그러므로 타입스크립트 등을 이용한 코드는 웹어셈블리와 호환 가능해야만 한다. 하지만 현재 딱 한가지 걸림돌이 있는데, 그것은 바로 웹어셈블리가 JS 엔진에 내장된 것과 같은 기존의 가비지 컬렉터와 어떻게 상호작용해야 하는지를 모른다는 점이다. 이 미래 기능의 아이디어는, 웹어셈블리에게 내장된 GC에 대한 일급 접근 권한과 하위 레벨 GC 원시 타입 및 연산을 제공하는 것이다.
  • ES6 모듈 통합. 브라우저는 현재 script 태그를 이용해서 자바스크립트 모듈을 로딩할 수 있도록 지원을 추가하고 있다. 이 기능이 추가된 후에는 <script src=url type=module> 같은 태그에서 url이 웹어셈블리 모듈을 가리킨다고 해도 동작할 수 있을 것이다.

결론

웹어셈블리는 지금도 빠르지만, 브라우저가 새로운 기능과 개선 사항을 구현하고 나면 더욱 더 빨라질 것이다.

Lin Clark 에 대해

Lin은 모질라 개발자 관계 팀의 엔지니어이다. 그녀는 자바스크립트, 웹어셈블리, Rust, Servo 등을 끄적거리며, 코드 카툰을 그린다.

코드카툰 : http://code-cartoons.com/
트위터 : @linclark

6 thoughts on “[번역] 웹어셈블리의 현재 위치와 미래

Leave a comment