- 전체
- HTML
- Web Design (웹디자인)
- XE 응용 개발
- wordpress plugin dev
- Javascript & JavaScript Application
- MEAN Stack : full stack javascript
- angular js & ionic framework
- bootstrap
- WebGL, Three.js and Babylon.js
- restful api design
- mobile web
- node.js 응용
- Cloud Service 응용
- 웹 어셈블리 개발 [WASM, WebAssembly]
- 마이크로서비스, MSA (microservice architecture)
- WebGL / WebGPU
- next.js 개발
- micro frontend (마이크로프론트앤드)
- 전자상거래/쇼핑몰
- 서버 클라우드 (aws, azure, google)
웹 어셈블리 개발 [WASM, WebAssembly] [웹 어셈블리, WSAM] サーバサイドはWebAssemblyの夢を見るか? – Node.jsでwasmってみた : 서버 측은 WebAssembly의 꿈을 꾸는가? – Node.js에서 wasm 해 보았습니다.
2023.08.27 16:28
[웹 어셈블리, WSAM] サーバサイドはWebAssemblyの夢を見るか? – Node.jsでwasmってみた
: 서버 측은 WebAssembly의 꿈을 꾸는가? – Node.js에서 wasm 해 보았습니다.
はじめに
こんにちは。次世代システム研究室のS.T.です。
Webの技術に興味のある方は「WebAssembly(wasm)」というキーワードを聞いたことがあるかもしれません。2019年に入ってからGoogle Earthのwasm実装のベータ版がリリースされたり、ディープな勉強会が開催されたり、密かな盛り上がりを見せている技術です。特に「Assembly」という語が入っているだけで私のような低レイヤ好きには非常に魅力的なものに見えます(実態はあまりAssembly感がないですが……)。
しかし、ゲームや動画など重量級のコンテンツを扱わないWebサイトでは活用できる機会はなかなかありません。さらに、Google V8に代表される高速なJavascriptエンジンの存在により、wasm導入によるパフォーマンス向上の効果とメンテナンスコスト増加のトレードオフを考えると、適用できる場面も限られてくるかと思います。特に、繰り返し呼び出されるような処理ではJavascriptエンジンの最適化によりネイティブに匹敵するパフォーマンスが出る場合もあり、wasmを使えばパフォーマンスが上がると言い切れる状況ではなくなっています。
そこで少し視点を変えて、サーバサイドアプリケーションでwasmを使うサンプルを紹介します。
おさらい
本題に入る前に、wasmについて本記事で必要な範囲でおさらいします。「wasmが何者であるか」については既に様々な解説記事が執筆されているため、詳細は割愛します。
- wasmはブラウザやNode.jsなどで高速に実行可能なコード
- Javascriptからwasmモジュールを呼び出して利用できる
- C/C++やRustなどの言語をwasmにコンパイル可能
- サンドボックス化された環境で実行
サーバサイドでwasm
今回注目したいのは、Node.jsでブラウザと同じwasmモジュールが利用可能な点です。つまり、サーバサイドとクライアントサイドで同じwasmモジュールを呼び出すことで、完全に同一の処理を行うことが可能になります。例えばサーバ側にデータを送りつつクライアント側で処理をして、その結果を先に表示して見かけ上の遅延を減らしたり、双方の処理結果を比較して不正なリクエストを防いだりといった利用方法が考えられます。
そこで、今回はWebアプリケーションのサーバサイドとクライアントサイドで同じコードを実行する実験を行います。Node.js、Expressで構成したWebアプリから、「C言語で記述してwasmにコンパイルした同一モジュール」をサーバ・クライアントの双方から呼び出し、計算結果と実行時間を計測します。比較のため、(浮動小数点の計算を意識しない)同じ処理をJavascriptで記述し、同一の計測を行います。コンパイルにはEmscriptenを使用します。検証にはUbuntu 18.04を使用しています。
サンプルアプリケーション
wasmファイルの作成
今回はグレゴリーライプニッツ級数を計算して円周率を求めるプログラムをwasmにしてみます。emccでコンパイルをしますが、今回は出力を.wasmファイルのみとし、ロードやインスタンス作成の処理も自分で実装することにします。
Node.jsからwasmの関数を呼び出す
メインのロジックにwasmで実装した関数を用いたAPIを作成します。
今回はサーバ起動時に同期的にインスタンスを作成しています。作成した関数は mod.exports._bake_pi() で呼び出しが可能です。計算結果をJSONで返却します。
ブラウザからwasmの関数を呼び出す
今回はブラウザでwasm実行、wasm実装API呼び出し、Javascriptで同じ計算する実装のそれぞれをWebWorkerで実装し、同時に実行します。インスタンスの作成自体はNode.js版とほぼ同じですが、Promiseを使った非同期処理を使用しています。
Node.jsのAPI呼び出しやJavascriptでの計算は特に変わった処理はせず、axiosでGETしたり、C言語と同じロジックでループしたりしています。実行時間の計測には performance.now() で取得した時間の差を使っています。
実行結果
作成したアプリケーションをローカルのVMで実行してブラウザからアクセスしてみます。検証環境のスペックは以下のとおりです。
| サーバ | クライアント | |
| OS / ブラウザ | Ubuntu 18.04 LTS | Windows 10 / Chrome |
| CPU | 2vCPU local VM | Intel Core i5-7500 (4 Core/4 Thread) |
| Memory | 2GB | 16GB |
以下のような実行結果が得られました。左側が計算された円周率、右側が実行時間です。wasm版はクライアントとサーバサイドで同じ結果が出ていますね。

クライアントサイドでwasmを動かしたものが最も高速、次いでサーバサイドでwasmを動かしたAPI、最後がクライアントサイドのJavascriptという結果です。実行時間についてはみなさんが予想していた通りの結果なのではないでしょうか?Javascript実装のみ計算結果が違うのは、浮動小数点の精度を意識した実装をしていないためです。
このように、wasmを使うとサーバサイドとクライアントサイドで細かい部分まで同一な処理を簡単に実現できます。最終的に後続処理に使う値はサーバサイドで計算したものだとしても、フロントエンドで高速に計算して得られた仮の結果でアニメーションなどを描画することで、ユーザ体験を向上させることができます。
おわりに
今回紹介したように、wasmはブラウザ以外でも実行できるため、サーバサイドアプリケーションにも適用することができます。一方、このような使い方が有効な場面というのは少なく、やはりwasmの出番は限られてしまいます。しかし、Wasmerのようにスタンドアロンでwasmのコードを実行する環境の開発も進んでいます。C/C++やRustで記述したコードから、様々なプラットフォームで動作し、安全性の高いバイナリを得ることができるのは大きな強みです。
wasmの実行環境や関連プロジェクトは日々進化していますし、今後利用事例なども増えてくるかと思いますので、興味のある方は一緒にウォッチしていきましょう!
最後に、次世代システム研究室では、グループ全体のインテグレーションを支援してくれるアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。
参考
MDN WebAssembly https://developer.mozilla.org/ja/docs/WebAssembly
소개
안녕하세요. 차세대 시스템 연구실의 ST입니다.
웹 기술에 관심이 있는 분은 " WebAssembly (wasm)"라는 키워드를 들었을지도 모릅니다. 2019년부터 Google 어스의 wasm 구현 베타 버전이 출시되거나, 깊은 공부회가 개최되거나, 은밀한 분위기를 보이고 있는 기술입니다. 특히 "Assembly"라는 단어가 들어있는 것만으로 나와 같은 낮은 레이어 좋아하는 것은 매우 매력적인 것처럼 보입니다 (실태는 그다지 Assembly 느낌이 없지만 ......).
그러나, 게임이나 동영상 등 중량급의 콘텐츠를 취급하지 않는 Web 사이트에서는 활용할 수 있는 기회는 좀처럼 없습니다. 게다가 Google V8로 대표되는 고속 Javascript 엔진의 존재로 인해 wasm 도입에 의한 성능 향상의 효과와 유지보수 비용 증가의 트레이드오프를 고려하면 적용할 수 있는 장면도 한정되어 있을까 생각합니다. 특히 반복적으로 호출되는 것과 같은 처리에서는 Javascript 엔진의 최적화에 의해 네이티브에 필적하는 퍼포먼스가 나오는 경우도 있어, wasm을 사용하면 퍼포먼스가 올라간다고 단언되는 상황이 없어지고 있습니다.
그래서 조금 시점을 바꾸어 서버 측 애플리케이션에서 wasm을 사용하는 샘플을 소개합니다.
오사라이
본제에 들어가기 전에 wasm에 대해 본 기사에서 필요한 범위로 드리겠습니다. "wasm이 누구인가?"에 대해서는 이미 다양한 해설 기사가 집필되어 있기 때문에 자세한 내용은 생략합니다.
- wasm은 브라우저나 Node.js 등에서 고속으로 실행 가능한 코드
- Javascript에서 wasm 모듈을 호출하여 사용할 수 있습니다.
- C/C++나 Rust 등의 언어를 wasm으로 컴파일 가능
- 샌드박스화된 환경에서 실행
서버측에서 wasm
이번 주목하고 싶은 것은 Node.js에서 브라우저와 같은 wasm 모듈을 이용할 수 있는 점입니다. 즉, 서버 측과 클라이언트 측에서 동일한 wasm 모듈을 호출하여 완전히 동일한 처리를 수행 할 수 있습니다. 예를 들어 서버 측에 데이터를 보내면서 클라이언트 측에서 처리를 하고, 그 결과를 먼저 표시하여 겉보기 지연을 줄이거나, 양쪽의 처리 결과를 비교하여 부정한 요청을 방지하는 등의 이용 방법이 생각할 수 있습니다.
그래서 이번에는 웹 애플리케이션의 서버 측과 클라이언트 측에서 동일한 코드를 실행하는 실험을 실시합니다. Node.js, Express로 구성한 웹 앱에서 "C 언어로 작성하여 wasm으로 컴파일한 동일한 모듈"을 서버 클라이언트 양쪽에서 호출하여 계산 결과와 실행 시간을 측정합니다. 비교를 위해(부동 소수점의 계산을 의식하지 않는다) 같은 처리를 Javascript로 기술해, 같은 계측을 실시합니다. 컴파일에는 Emscripten을 사용합니다. 검증에는 Ubuntu 18.04를 사용하고 있습니다.
샘플 애플리케이션
wasm 파일 만들기
이번에는 그레고리 라이프 니츠 급수를 계산해 원주율을 구하는 프로그램을 wasm으로 해 보겠습니다. emcc로 컴파일을 합니다만, 이번은 출력을 .wasm 파일만으로 해, 로드나 인스턴스 작성의 처리도 스스로 구현하기로 합니다.
Node.js에서 wasm 함수 호출
메인 로직에 wasm으로 구현한 함수를 이용한 API를 작성합니다.
이번에는 서버 시작시 동기적으로 인스턴스를 만들고 있습니다. 작성한 함수는 mod . exports . _bake_pi () 로 호출이 가능합니다. 계산 결과를 JSON으로 반환합니다.
브라우저에서 wasm 함수 호출
이번에는 브라우저에서 wasm 실행, wasm 구현 API 호출, Javascript에서 같은 계산하는 구현 각각을 WebWorker로 구현하고 동시에 실행합니다. 인스턴스 작성 자체는 Node.js 버전과 거의 동일하지만 Promise를 사용한 비동기 처리를 사용합니다.
Node.js의 API 호출이나 Javascript에서의 계산은 특별히 바뀐 처리는 하지 않고, axios로 GET하거나 C언어와 같은 로직으로 루프하거나 하고 있습니다. 실행 시간의 측정에는 performance.now() 로 취득한 시간의 차이를 사용하고 있습니다.
실행 결과
작성한 애플리케이션을 로컬 VM에서 실행하여 브라우저에서 액세스해 봅니다. 검증 환경의 스펙은 다음과 같습니다.
| 서버 | 클라이언트 | |
| OS / 브라우저 | 우분투 18.04 LTS | Windows 10/Chrome |
| CPU | 2vCPU 로컬 VM | Intel Core i5-7500 (4 Core/4 Thread) |
| Memory | 2GB | 16GB |
다음과 같은 실행 결과를 얻었습니다. 왼쪽이 계산된 원주율, 오른쪽이 실행 시간입니다. wasm판은 클라이언트와 서버측에서 같은 결과가 나오고 있네요.

클라이언트 측에서 wasm을 움직인 것이 가장 빠르고, 다음으로 서버 측에서 wasm을 움직인 API, 마지막이 클라이언트 측의 Javascript라는 결과입니다. 실행 시간에 대해서는 여러분이 예상하고 있던 대로의 결과가 아닐까요? Javascript 구현만 계산 결과가 다른 것은, 부동 소수점의 정밀도를 의식한 구현을 하고 있지 않기 때문입니다.
이와 같이 wasm을 사용하면 서버측과 클라이언트측에서 세세한 부분까지 동일한 처리를 쉽게 실현할 수 있습니다. 최종적으로 후속 처리에 사용하는 값은 서버 측에서 계산한 것이라도 프런트 엔드에서 고속으로 계산하여 얻은 임시 결과로 애니메이션 등을 그려서 사용자 경험을 향상시킬 수 있습니다. 합니다.
결론
이번에 소개한 것처럼 wasm은 브라우저 이외에서도 실행할 수 있으므로 서버측 애플리케이션에도 적용할 수 있습니다. 한편, 이러한 사용법이 유효한 장면이라고 하는 것은 적고, 역시 wasm의 차례는 한정되어 버립니다. 그러나 Wasmer 처럼 독립형으로 wasm 코드를 실행하는 환경 개발도 진행되고 있습니다. C/C++나 Rust로 기술한 코드로부터, 다양한 플랫폼에서 동작해, 안전성이 높은 바이너리를 얻을 수 있는 것은 큰 강점입니다.
wasm의 실행 환경이나 관련 프로젝트는 날마다 진화하고 있어, 향후 이용 사례등도 늘어날까라고 생각하므로, 흥미가 있는 분은 함께 워치 해 갑시다!
마지막으로 차세대 시스템 연구실에서는 그룹 전체의 통합을 지원해 주는 아키텍트를 모집하고 있습니다. 어플리케이션 개발자의 분, 차세대 시스템 연구실에 흥미를 가져 주시는 분이 계시시면, 꼭 모집 직종 일람으로부터 응모를 부탁 합니다 .
참고
MDN WebAssembly https://developer.mozilla.org/en/docs/WebAssembly
[출처] https://www.gmo-jisedai.com/blog/dream-of-wasm/
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
댓글 0
| 번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
|---|---|---|---|---|
| 4 |
ActionScript 3.0 학습에 도움이 되는 팁
| 졸리운_곰 | 2014.06.22 | 781 |
| 3 | ActionScript 3.0 : 어려울까요? 안 어려울까요? - (3) | 졸리운_곰 | 2014.06.22 | 762 |
| 2 | ActionScript 3.0 : 어려울까요? 안 어려울까요? - (2) | 졸리운_곰 | 2014.06.22 | 798 |
| 1 | ActionScript 3.0 : 어려울까요? 안 어려울까요? - (1) | 졸리운_곰 | 2014.06.22 | 904 |

