본문으로 바로가기

웹어셈블리는 자바스크립트가 아닌 다른 프로그래밍 언어로 작성된 코드를 브라우저에서 실행시키기 위한 방법이다. 그래서 사람들이 웹어셈블리가 빠르다고 이야기하는 건, 자바스크립트와 비교했을 때 빠르다는 말이다.

 

성능에 있어서 가장 큰 차이점은 컴파일을 언제 하는가(컴파일 언어와 인터프리터 언어), 실행 코드가 Assembly로 바로 실행되는가 중간코드를 실행하기 위한 VM(Virtual Machine)이 있는가로 볼 수 있겠다. 아시다시피 자바스크립트는 그 유연함과 생산성에 이점이 있는 대신 런타임에 해석되고 컴파일 및 실행되기 때문에 성능에 있어서는 포기해야 할 부분이 있다.

C : 정적 컴파일 + Assembly
Java : 인터프리터 + VM

 

- 컴파일 방식에 대한 이해

 

본인의 포스팅을 인용하자면 컴파일 기법에는 크게 두 가지가 있다. 인터프리터 방식과 정적 컴파일 방식.

 

python의 경우 인터프리터 방식으로 런타임시에 바이트 코드를 한 줄씩 읽어나가며 코드를 실행한다. 이 방법은 동일한 메서드를 여러번 사용하는 경우 중복해서 번역하는 비효율이 있다.

 

C의 경우 정적 컴파일을 진행한다. 컴파일 먼저 다하고 실행하기만 한다. 빠르지만 단점으로는 초기 구동에 시간이 걸린다는 것이다. 컴파일러는 코드를 좀더 빠르게 실행하기 위해 전체 코드를 둘러보고 최적화를 진행하는데 이 때문에 시간이 조금 더 소요된다. 인터프리터는 런타임에 한 줄 한 줄 실시간 번역이기 때문에 이런 최적화를 할 수 없다.

 

이런 두 컴파일 방식에 대한 개선책으로 JIT가 도입되었다.

 

JIT는 기본적으로 인터프리터 방식으로 작동하지만 번역한 내용을 캐싱해두었다가 동일한 메소드를 실행할 때 캐싱된 내용을 사용한다. 대표적으로 JIT 컴파일 방식을 사용하는 언어로 Java가 있다. java는 우선 java 코드를 바이트 코드(.class)로 컴파일한 후 해당 바이트 코드를 JIT 방식으로 변환해나간다. 아무리 JIT가 캐싱 때문에 인터프리터보다 빠르다고는 해도 느리긴 느리다.

 

 

- javascript의 JIT 컴파일

(이 글을 꼭 읽어보자)

 

한편 javascript를 실행하는 브라우저들은 속도 경쟁을 위해 저스트-인-타임(Just-in-time) 컴파일러, 즉 JIT를 장착했고 이는 javascript 성능 향상에 도움이 되었다.

 

사실 모든 브라우저의 js 엔진이 동일한 JIT 컴파일을 이용하지는 않고 끊임없이 개선하는 중이다. 대체적으로 js에서 이루어지는 JIT 컴파일은 다음과 같다.

 

자바스크립트 엔진에 모니터(혹은 프로파일러)라고 불리는 부분을 추가했다. 이 모니터는 코드가 실행되는 것을 관찰하면서 해당 코드가 얼마나 많이 실행되고, 어떤 타입이 사용되는지를 기록한다. 자주 사용되는 (warm, 또는 hot)한 코드가 있다면 정적 컴파일러처럼 최적화를 하여 사용한다. 뿐만 아니라 타입 특수화 등 각종 최적화와 js 속도를 개선하기 위한 많은 노력들이 있다. 굉장히 어려운 부분이고, 브라우저 점유율을 높이기 위한 기업간의 경쟁이다.

 

여튼 이러한 경쟁 덕분에 2008년을 기념으로 js의 실행 속도는 10배 정도나 높아졌다고. 게다가 서버 사이드에서 javascript를 사용하게 되면서 js의 속도 향상 개선은 지속적으로 이루어지고 있다. 그러나 정적 컴파일 언어에 비하면 느린 것은 사실이다.

 

https://dongwoo.blog/2017/06/06/%eb%b2%88%ec%97%ad-%ec%b9%b4%ed%88%b0%ec%9c%bc%eb%a1%9c-%ec%86%8c%ea%b0%9c%ed%95%98%eb%8a%94-%ec%9b%b9%ec%96%b4%ec%85%88%eb%b8%94%eb%a6%ac/

 

 

 

- WASM은 어셈블리언어와 조금 다르다

 

우선 기계어와 어셈블리 언어에 대한 이해는 필자의 포스트인  darrengwon.tistory.com/776를 참고하자.

웹어셈블리는 일반 어셈블리 언어와는 좀 다르다. 일반 어셈블리 언어(이하 어셈블리)는 직접적으로 기계를 대상으로 하는 언어이다.

 

그러나 웹 어셈블리는 사용자의 기계에서 실행될 코드를 웹을 통해서 전달하기 때문에, 코드가 실행될 대상 아키텍쳐가 무엇인지를 알 수가 없다. 웹어셈블리는 실제의 물리적인 기계가 아닌 개념상의 기계를 위한 언어이다. 특정한 하드웨어를 위한 특정 기계 코드에 직접적으로 맵핑되지 않는다.

 

https://dongwoo.blog/2017/06/06/%eb%b2%88%ec%97%ad-%ec%9b%b9%ec%96%b4%ec%85%88%eb%b8%94%eb%a6%ac-%eb%aa%a8%eb%93%88%ec%9d%98-%ec%83%9d%ec%84%b1%ea%b3%bc-%eb%8f%99%ec%9e%91/

 

 

- C를 이용하여 WASM을 작성하는 법

 

자세한 방법은 이 글을 참고하자

 

현재 웹어셈블리를 가장 잘 지원하는 컴파일러 도구 모음(toolchain)은 LLVM이라 불린다. 많은 수의 프론트엔드와 백엔드가 LLVM으로 변환이 가능하다.

 

우리가 C를 이용해 웹어셈블리를 작성한다고 가정하자. 우리는 clang 프론트엔드를 이용해서 C를 LLVM 중간 표현 방식으로 변환할 수 있을 것이다. LLVM의 IR로 변환하고 나면, LLVM이 그것을 이해할 수 있으므로 LLVM이 몇가지 최적화를 할 수 있게 된다.

 

 

어쨌거나 어떤 도구 모음을 사용했는지와는 관계 없이, 최종 결과는 .wasm 으로 끝나는 파일이 된다.

 

실용적으론 LLVM WASM backend보다 Emscripten이 더 편하다고들한다.

정리하자면 C/C++ 코드 작성하고 Emscripten를 이용하여 WebAssembly 모듈로 변환할 수 있고 이 .wasm을  assemblyscript-loader wasm-loader 와 같은 웹팩 로더를 사용해서 로딩, 번들링한다.

 

프론트엔드 개발자에게 빠른 성능을 얻기 위해 WebAssembly 모듈을 얻기에는 너무나도 먼 길이 기다리고 있다. make, llvm, C/C++, Compile, Linking 등과 같은 생소한 과정들을 난감함과 고통과 배움을 통해 WebAssembly로 승화시켜야 하는 것이다. 그리고 만들어진 모듈을 Webpack이나 rollup 같은 개발환경에서 통합시켜야 하는 과정을 거쳐야 한다. (와.. webpack만 해도 죽을 맛인데 ㅋㅋㅋㅋ)

 

C/C++과 같은 네이티브 언어로부터 컴파일하여 WebAssembly를 사용하기에는 앞서 살펴본 것처럼 절차가 복잡하다.익숙한 자바스크립트 언어 계열로 작성하고 바로 WebAssembly로 컴파일 되면서 Webpack을 사용하여 바로 번들링 하기 위한 AssemblyScript가 개발되고 있으니 다행이지만 결국에는 C/C++ 배워야 한다.

 

 

- AssemblyScript

 

WebAssembly로 변환할 수 있는 언어의 조건은 변수의 타입을 확인할 수 있는 언어이어야 한다는 특징이 있다. C/C++, Rust, TypeScript(WebAssembly 컴파일 타겟 추가에 대한 논의) 등의 언어들이 WebAssembly로 변환될 수 있는데, Typescript의 하위집합인 "AssemblyScript" 또한 WebAssembly로 변환이 가능하다. AssemblyScript를 선택한 이유는 사용성이다. NPM에 등록이 되어 있고 프론트 엔드 개발자가 보다 쉽게 WebAssembly 코드를 테스트할 수 있기 때문이다.

 

assemblyscript를 NPM으로 설치하면 커맨드라인에서 보다 쉽게 컴파일 하여 .wasm(WebAssembly) 파일을 만들어 낼 수가 있다. 또한 생성된 WASM파일을 모듈로 사용할 수 있는 assemblyscript-loader wasm-loader도 있는데 둘의 차이점은 전자는 코드 내에서 WASM 모듈을 로딩할 수 있고 옵션이 많고, 후자는 Webpack 로더로 제공되고 좀 더 쉽게 사용하고 번들링도 가능하다는 점이다.

 

www.npmjs.com/package/assemblyscript-loader

www.npmjs.com/package/wasm-loader

개량 : github.com/dongsik-yoo/assemblyscript-live-loader (사용하지 말고 연구해서 내가 만들어내자. 어차피 npm에 등록도 안되어 있음 ㅋㅋ)

 

 

참고한 글과 추후 공부할 것들)

 

 

웹 어셈블리를 보다 쉽게 웹 어플리케이션에 적용하는 방법 : TOAST Meetup

웹 어셈블리를 보다 쉽게 웹 어플리케이션에 적용하는 방법

meetup.toast.com

 

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

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

dongwoo.blog

 

egghead.io

Screencast workshops for professional web developers.

egghead.io

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체