WebAssembly 란?

youseock·2024년 2월 29일

[JS] WebAssembly

목록 보기
1/4
post-thumbnail

Wasm에 대해서 알아보고, Wasm의 등장 배경에 대해서 다루는 글입니다.

Wasm에 대해서 알아보자

the Web has become the most ubiquitous application platform ever, and yet by historical accident the only natively supported programming language for that platform is javascript.
by Web Assembly 개발자 팀

웹 어셈블리(이하 Wasm) 개발팀은 자바스크립트가 웹에서 동작하는 유일한 프로그래밍 언어가 된 이유는 우연일 뿐이라고 지적한다. 브라우저가 자바스크립트만 해석해야할 이유도 필요도 없다는 사실에 주목하자.

Wasm은 웹 브라우저에서 실행할 수 있는 새로운 형식의 파일을 의미한다. C, C++, RUST 등의 컴파일 언어만이 아니라 Python과 같은 스크립트 언어를 포함하여 약 30개의 언어를 Wasm 형식으로 바꿔 사용할 수 있다. Wasm은 바이너리 포멧으로 변형되기 때문에 웹에서도 네이티브에 가까운 속도로 실행될 수 있어, 웹 플랫폼 기반한 새로운 유형의 서비스를 제공할 수 있다는 큰 장점이 있다.

💡 Wasm의 앞머리가 Web이라 웹에서만 돌아간다고 생각하지 말자!

Wasm은 여러 플랫폼 위에서 네이티브에 가까운 속도로 실행되는 것을 목표한다.

Wasm은 2017년에 등장했고, 현재는 웹 표준이다.

간단한 C 코드를 WAT와 Wasm으로 변환 해보자

C 언어

int add(int x, int y){
	return x + y;
}

WAT 형식으로 변환

  • WASM 커뮤니티 그룹은 Wasm가 저수준 어셈블리 언어지만, 사람이 충분히 읽을 수 있는 수준의 텍스트 형식을 제공하는 것을 목표로 한다. 이러한 텍스트 형식을 웹 어셈블리 텍스트 포멧이라고 하며, Wasm과 자유롭게 상호변환해서 사용할 수 있다.
(module
 (table 0 anyfunc)
 (memory $0 1)
 (export "memory" (memory $0))
 (export "add" (func $add))
 (func $add (; 0 ;) (param $0 i32)
	 (param $1 i32) (result i32)
	(i32.add
		(get_local $1)
		(get_local $0)
	)
 )
)

Wasm 형식으로 변환

wasm-function[0]:
  sup rsp, 8
  mov ecx, esi
  mov eax, ecx
  add eax, edi
  nop
  add rsp, 8
  ret

왜 Wasm이 등장했을까 ❓?

Wasm이 브라우저에서 해석 가능한 네 번째 언어가 된 이유는 다음과 같다.

  • 바이너리 파일이기 때문에 용량이 적다.
  • 기계어에 가깝기 때문에 실행 속도가 빠르다.
  • Wasm은 안전한 환경에서 실행되기 때문에, 보안성이 좋다.
  • 다양한 언어로 작성된 라이브러리 및 코드를 가져와서 웹에서 사용할 수 있다.
  • 메모리를 직접 할당하고 해제할 수 있어, 예측가능한 성능을 기대할 수 있다.

왜 Wasm이 JavaScript보다 빠를까 🚀

[과거] JavaScript 코드의 실행 과정

예시 이미지 사진 출처

스크립트 언어가 가진 한계

자바스크립트(JIT 컴파일러 도입 이전)는 3 가지 단계로 코드를 해석했다. 먼저 코드를 parsing하고 execute한 뒤에 garbage collection순으로 코드를 실행했다. 위 그림을 보면 execute가 대부분의 시간을 차지하는 것을 알 수 있는데, 스크립트 언어가 가진 한계이다.

최근 스크립트 언어들은 실행 시간을 줄이기 위에 JIT(Just-In-Time) 컴파일 기술을 도입해 실행 성능을 향상 시켰으며, 자바스크립트도 마찬가지이다.

[현재] JavaScript 코드의 실행 과정

예시 이미지 사진 출처

JIT 컴파일러 도입 후 성능 개선

JIT 컴파일러가 도입되며 3 단계로 이루어 지던 자바스크립트 실행이 5 가지 단계로 변경됐다. execute 전에 최적화(optimize)하는 과정을 둬서 실행 시간을 획기적으로 줄일 수 있었고, 이를 토대로 웹 플랫폼 외의 곳에서도 자바스크립트 언어가 활용되는 계기가 됐다.

최적화 단계에 대해서 생각해보자

스크립트 언어의 경우 loop에 해당하는 작업도 매번 다시 translate하는 단점이 있다. JIT은 컴파일이 필요하다고 판단이 들 때 컴파일 하는 방식을 의미한다. 컴파일도 비용이 들기 때문에 컴파일이 필요하다는 확률적인 결정을 아주 잘 내려야 한다는 것이다.

그렇지 않다면 JIT을 도입해도 성능 개선을 기대할 수 없다. 컴파일 비용, 컴파일이 필요한 지 아닌지 모니터링 하는 비용, 잘못된 최적화를 다시 조정하는 비용 등이 필요하게 되니 주의해야 한다.

운 좋게도 브라우저나 Node.js가 사용하는 자바스크립트 엔진은 매우 성능이 좋으니 믿고 사용해도 된다.

JavaScript vs Wasm을 직접 비교 해보자

사진 출처

parse

JavaScript 엔진은 문자열을 의미 있는 토큰들로 변환한 뒤에 구문을 분석해 AST라는 추상 구문 트리를 생성한다. JIT 컴파일러를 사용하는 엔진의 경우 AST를 기계가 바로 해석할 수 있는 바이트코드(Bytecode)로 변환하는 과정을 가치게 된다.

Wasm은 이미 바이너리 코드이기 때문에 디코딩하고 오류 검사만 진행한다.

compile + optimize

둘 다 같은 과정을 거치지만 WASM이 더 빠르다. Wasm이 기계어에 훨씬 가깝고, 모니터링과 같은 과정이 필요없기 때문이다.

re-optimize

JavaScript를 실행하는 과정에만 존재하며, 비슷한 환경에서 재실행되길 기대했던 컴파일 대상이 그렇지 않을 때 일어난다.

execute

해당 단계는 Wasm이 JavaScript에 비해 항상 빠른것은 아니라는 사실에 주목하자. JavaScript도 최적화를 잘 한 상태라면 Wasm과 같은 execute 속도를 기대할 수 있다. 그렇다고 JavaScript가 더 빠른 것은 아니다. WASM에 비해 같거나 느리다.

garbage collection

Wasm는 GC를 지원하지 않아 수동으로 메모리를 관리해야 한다.메모리 관리를 개발자가 직접 해야한다는 것은 단점이지만, 메모리 성능에 대해 신뢰할 수 있다는 장점이 있다.

이렇게 장점이 많은 Wasm을 왜 안 쓸까

Wasm은 Figma, AutoCAD Web, Google Earth와 같이 3D 그래픽 처리, 웹 플랫폼 기반 게임 등과 같은 특정 서비스에 사용된다.

Wasm은 CPU 집약적인 작업이 필요한 경우에 높은 성능을 기대할 수 있고 CPU 집약적인 서비스에만 사용해야 한다고 생각한다. 일반적인 웹 어플리케이션의 경우에는 Wasm을 사용할 이유가 없다.

💡 특정한 언어로 된 라이브러리나 애플리케이션을 웹에서 사용하고 싶다면 말리진 않겠지만, 아마도 비슷한 기능을 제공하는 라이브러리가 자바스크립트에도 있을테니 그것을 사용하자.

이렇게 생각하는 이유는 다음과 같다.

  1. 개발 과정에서 컴파일을 주기적으로 해줘야 하는 단점이 있다.
  2. Wasm 파일을 가져와 실행 시키는 것이 일반적인 자바스크립트 실행 방법과 다르다.
  3. js로 랩핑한 상태로 컴파일할 수 있지만, 용량이 커진다.
profile
자바스크립트 애호가

0개의 댓글