WASM에 대하여
WebAssembly(WASM)은 웹 브라우저에서 실행 가능한 바이트코드 웹 표준이다.
이번 글은 WASM의 사용 방안, JS와의 성능 차이 등을 정리해 보았다.
[주의]
본문은 JS, WASM의 정의 및 생태계를 대략적으로 파악하고 있음을 전제로 한다.
배경 설명은 다 자르고, 실리적이고 기술적인 내용만 있음을 알린다.
WASM의 대표적 특징
- 연산 집약적인 작업 용도이다
- 바이트코드로 사전 컴파일하여, 클라이언트(브라우저)의 컴파일 과정이 필요 없다
JS-WASM 간의 소통
JS 내에서의 WASM 함수 호출 방식은 같다.
여기서 함수의 인자는 참조가 될 수는 없고, 값 복사를 통해서 전해진다.
기본적으로 WASM 인스턴스에 사용될 메모리는 JS에서 ArrayBuffer를 통해 구현된다.
물론 이를 수동으로 할 필요는 없으며, WASM 인스턴스와 JS 모듈로 묶어 제공해주는 바인딩 툴들을 이용할 수 있다.
JS와의 깡성능 차이
기본적으로 컴파일 시간이 사라지며 로딩이 빨라지는 이점을 가질 것은 알 수 있겠다.
그러면 런타임 시간은 어느 정도일까?
The performance gain we measured with Rust (both implementations) is up to 20% compared to the baseline JavaScript implementation - measured on average.
This may sound like a win for Rust, but is actually a very small gain compared to the efforts required.
To WASM or not to WASM? - DEV Community
네이티브 JS대비 성능 향상은 20%로, 성능이 드라마틱하게 증가하지는 않는다.
오히려 JS 대비 성능이 하락하는 지점이 존재하기도 한다.
WASM 실행에 대해서는 다양한 요인(샌드박스 실행, JS-WASM 간 호출 병목) 들이 존재하기에, 이것들에 의한 결과로 성능 하락이 발생할 수 있겠다.
물론 현재 시점으로도 WASM은 매우 초기적인 기능이며, 현재진행형으로 JS엔진에서의 최적화가 이루어지고 있는 상황이다. JS와 WASM의 본질적인 구조가 다른 만큼, 시간이 지나며 점차 성능차이가 벌어지지 않을지 예상해 본다.
SIMD
JS에서는 현재로서 SIMD 기능을 사용할 방법이 없는데 반해, WASM에서 해당 기능을 지원한다.
SIMD가 행렬 연산에 폭발적인 성능을 발휘하기에, 이를 응용해서 얻는 성능 향상도 클 수 있다.
이에 대해 TensorFlow의 벤치마크 내용을 인용하면 다음과 같다.
이미지 처리 및 3D 연산 영역처럼, 행렬 연산이 필요한 경우에는 WASM을 활용하는 방안이 좋을 것 같다.
WASM의 스레딩
C, C++, Rust의 WebAssembly 스레드 사용 | Articles | web.dev
다른 언어로 작성된 멀티스레드 애플리케이션을 WebAssembly로 가져오는 방법을 알아봅니다.
web.dev
WASM에서의 스레딩은 JS에 존재하는 Worker, SharedArrayBuffer, Atomics 를 기반으로 구현되는 기능이다. 그렇기에 WASM 고유의 특징이라고 보긴 어려우며, 바인딩 툴을 이용한 코드 작성의 이점이라고 봐야 하겠다.
다만 JS와 독립적인 WASM Atoms와 같은 것들이 현재 표준화를 거치고 있는 상황이기에, 후에 스레딩에 대한 이점이 증가할 가능성이 있다.
현재 각각의 바인딩 툴에서 지원되는 스레딩 라이브러리들은 대략적으로 이렇다.
C(emscripten): pthread
C++(emscripten): std::thread, std::async
Rust(wasm-bindgen): wasm-bindgen-rayon (std::thread 미지원)
기타 등등...
브라우저 밖에서의 WASM
[번역] 웹어셈블리에 주목하라
원문: https://harshal.sheth.io/2022/01/31/webassembly.html
medium.com
웹 영역 외에서는 WASI라는 개별적인 표준 또한 발전하고 있다.
이를 기반으로 한 wasmtime, wasmer 등의 런타임 또한 탄생했는데, 이것들은 브라우저 외의 독립적인 런타임으로서 WASM을 실행하는 것을 목표로 한다.
또한 다양한 언어들에서 WASM으로의 컴파일을 지원한다. 이 덕분에 특정 언어에서 우세한 라이브러리 혹은 프레임워크를 다른 언어에서 이용하는 언어 간의 범용성이 증가하며, 특정 언어의 종속적인 기술을 프로젝트에 활용할 수 있는 가능성이 확장되었다.
이에 대한 대표적인 예시들이 있다.
- Redpanda: 메시지 브로커 기술로, WASM을 통해 사용자 지정 데이터 변환 작성, 특정 언어나 스키마 따위에 종속되지 않은 작성이 가능함
- figma: C++ 기반 그래픽 라이브러리인 Skia를 WASM 컴파일을 통해 JS 플랫폼에서 사용, 새로운 라이브러리 개발 부담을 효과적으로 감소시킴
- lichess.org: 웹 체스 게임으로, 기존의 서버에서 실행되었던 체스봇 프로그램을 WASM을 통해 클라이언트에서 실행, 서버의 연산 부하를 절감함
요약
- WASM을 단지 성능을 목적으로 도입하는 것은 노력 대비 불필요하다. (차라리 Web Worker 또는 N-API 등을 고려해보자)
- 현재 JS에서 이용 불가능한 SIMD 기능을 지원한다.
- 스레딩 코드를 작성하는 데에 이점이 있다.
- 언어에 종속되지 않고 라이브러리 및 기술을 도입할 수 있다는 점 또한 강점이다.
기타 인용