2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

既存のC/C++ライブラリをWebAssemblyにコンパイルしてブラウザでも活用する方法

Posted at

はじめに

最近、ブラウザ上でネイティブ級の高速処理を実現できる技術としてWebAssembly(Wasm)が注目を集めています。私は、電子回路シミュレータの内部構造に興味があり、そこで使える数値線形代数ライブラリ(例:KLU)や、常微分方程式ソルバを含むSUNDIALSのようなC/C++で書かれた数値計算ライブラリをWebAssemblyでも動かしてみたいと考えています。

本記事では、こうした既存のC/C++ライブラリをWasmにコンパイルして利用する際のメリットや注意点を解説します。数値計算だけでなく、画像処理、機械学習、暗号など広くC/C++ライブラリを再利用したい方の参考になれば幸いです。


1. なぜC/C++ライブラリはWasmにコンパイルしやすい、と言われるのか?

1.1 LLVMベースのツールチェーンが充実

  • WebAssemblyはLLVMをバックエンドとしており、EmscriptenClangのWebAssemblyターゲットが整備されています。
  • Emscripten: 代表的なツールチェーン。emccコマンドでC/C++→Wasmコンパイルが可能。
  • Clang/LLVM: -target wasm32-unknown-emscriptenなどで直接Wasmバイナリを生成できるオプションもあります。

1.2 C/C++の移植性の高さ

  • C/C++はもともとWindows、Linux、macOS、組込みなどマルチプラットフォーム対応の歴史があり、OS非依存コードを中心とするライブラリが多いです。
  • POSIX関数や標準Cライブラリを使う程度なら、大きな修正なしでビルドが通るケースが多い。
  • Emscriptenにはファイルシステムエミュレーションスレッドサポート等もあり、ある程度のOS機能を擬似的に再現できます。

1.3 豊富な既存ライブラリ資産

  • C/C++には画像処理(libpng, libjpeg)、音声/動画、暗号、機械学習などの成熟ライブラリが多数存在します。
  • これらをWebAssemblyにコンパイルすることで、一からWeb用に書き直す手間を大幅に省き、JavaScript(やTypeScript)から呼び出して高性能な処理を利用できます。

1.4 JavaScriptとのブリッジ(FFI)が容易

  • EmscriptenのcwrapccallEM_JSマクロなどで、C/C++関数とJavaScriptを簡単に相互呼び出しできます。
  • Web API(WebGL、Audioなど)との連携用のラッパーコードもある程度整備されているため、フロントエンドでリッチな機能を実装しやすいです。

2. できない/難しいケースはどんなとき?

2.1 OS依存やハードウェアアクセスが強い場合

  • デバイスドライバやカーネル機能を直接呼び出すコードは、ブラウザ上では実行不可能。
  • OpenGLやDirectXのようなネイティブAPI依存部はWebGLやWebGPU等へ置き換えが必要な場合があります。

2.2 プラットフォーム固有APIの多用

  • WindowsのWin32 API、Linux専用のシステムコール、macOSのCocoaフレームワークなどに強く依存するライブラリは移植困難。
  • Emscriptenには対応APIがない場合が多いので、stub(ダミー)を作るか実装を切り離す必要があります。

2.3 並列化や高度な並行処理

  • WebAssemblyのスレッド対応は近年進化中ですが、MPIのようなプロセス間通信モデルには未対応。
  • OpenMPを多用するコードはEmscriptenオプションとブラウザのSharedArrayBufferサポート次第で制限があります。

2.4 大規模ライブラリの依存関係

  • BLAS/LAPACKなど下層の数値ライブラリすべてをWasmでビルドし直す必要がある場合も。
  • GUIツールキットや外部プロセス呼び出しなど、Web上で再現困難な部分は機能を削減するしかありません。

2.5 セキュリティやライセンス上の問題

  • ソースコードやバイナリをWeb公開できないライセンス形態だと移植自体が難しい。
  • Web配布すると、逆アセンブルや改変リスクがある点にも留意が必要です。

3. 実例:KLUやSUNDIALSなどの数値計算ライブラリ(自分が使いたい)

3.1 KLU(Sparse LU分解ライブラリ)

  • SuiteSparseに含まれるスパースLU分解ライブラリ。
  • 主にC言語で書かれており、OS固有のコードが少なく、数値アルゴリズム主体。
  • スレッドやBLAS/LAPACK依存をオフにするかEmscripten用にビルドすれば、比較的スムーズに移植できる可能性大。

3.2 SUNDIALS(ODE/DAEソルバ)

  • CVODEやIDA、KINSOLなど多彩な数値ソルバ群。
  • シリアル版のみであればブラウザでも十分動作可能。
  • 並列化(MPIやOpenMP)を多用すると難易度が上がるが、オフにすれば移植しやすい。

結論:C/C++主体の数学ライブラリなので、OS依存部分を外せばWebAssemblyに移植できる確率は高い


4. 実際にコンパイルする流れ(Emscriptenを例に)

以下の図は、C/C++ソースコードをEmscriptenでビルドして、ブラウザ上でWasmモジュールを呼び出すまでのフローを表しています。

  1. Emscriptenのインストール
    git clone https://github.com/emscripten-core/emsdk.git
    cd emsdk
    ./emsdk install latest
    ./emsdk activate latest
    source ./emsdk_env.sh
    
  2. ライブラリのソースを取得し、configure/cmake
    • emconfigure ./configureemcmake cmake .. などEmscripten用のwrapperで環境設定
  3. コンパイル・リンク
    • emmake makeでビルド → .wasm + .js(ブリッジ) が生成
    • または emcc mylib.c -o mylib.js -s MODULARIZE=1 ... 等の直接指定
  4. JavaScript側でロード・呼び出し
    const Module = await MyLib();   // EmscriptenのMODULARIZE生成
    const result = Module._my_function(123, 456);
    console.log(result);
    
    • Emscriptenのcwrapccallを使えばよりシンプルに呼び出せます

5. 結論とまとめ

  • 調べた限り、C/C++ライブラリをWebAssemblyにコンパイルできる確率は、OS依存の少ない“数値計算系”や“アルゴリズム系”ならおおむね7~8割以上で成功するようです。
  • GUIや並列化、特殊なハードウェアアクセスが絡むほど移植は困難になります。
  • しかしながら、電子回路シミュレータ内部で使われるKLUやSUNDIALSなどは、比較的OS依存が少ないため、十分移植して動かせる可能性が高い、と思いました。
  • 一度Wasm化できれば、ブラウザ上のUIやサーバーレス環境で強力なC/C++ライブラリを再利用できるため、挑戦する価値は大いにあると思います。

FAQ

Q1. EmscriptenでビルドしたWasmはネイティブコードと比べてどのくらい遅くなりますか?

A1. 一般的にはネイティブコードより多少のオーバーヘッドがありますが、JIT最適化やAOTを活用することで「おおむねネイティブの7〜9割程度」の性能が出ると言われています。起動時間やメモリ効率では有利な場合もあります。

Q2. 逆アセンブルされてしまうリスクはどうすればいいですか?

A2. WebAssemblyはバイナリ形式ですが、読み出しや逆アセンブルを完全に防ぐことはできません。ソースコードを保護したい場合、難読化DRMのような対策を検討する必要があります。

Q3. ブラウザ以外でWasmを動かす場合でもC/C++ライブラリ移植はしやすいですか?

A3. サーバーサイドやサーバーレス環境(WASI対応ランタイムなど)でも、同様にEmscriptenやClangでコンパイルできます。ブラウザ特有のAPIは不要な分、さらにOS依存コードを排除しやすいかもしれません。

Q4. MPIやOpenMPをどうしても使いたい場合、まったく無理なのでしょうか?

A4. WebAssemblyのスレッドサポートはあり、OpenMPの一部をサポートする試みがあります。ただしブラウザで有効にするにはSharedArrayBuffer等の仕組みが必要で、セキュリティ要件が厳しいです。MPIはさらに困難ですが、将来のWASI拡張に期待があるかもしれません。

Q5. Spice本体すらWasm化することはできますか?

A5. SpiceはUNIX系APIに依存する部分も多いですが、理論上はEmscriptenで対応可能なところは多いです。GUIやマルチスレッド部分、外部プログラム呼び出し等を調整すれば、一部機能を削減しつつ移植する事例は考えられます。

Q6. 大規模な数値計算(例えば100万以上の未知数を持つ方程式)をブラウザで実行するとパフォーマンスが不安です。

A6. 計算時間は実装やアルゴリズムに左右されますが、Wasmによるネイティブ級の性能向上があっても、ブラウザでの実行にはメモリ上限やタブのCPU時間制限などがある場合があります。大規模計算はサーバーサイドWasmやエッジランタイムを検討するのも手です。


まとめ

WebAssemblyは、ブラウザからクラウド、エッジ、そしてIoTデバイスまでを繋ぐ汎用実行プラットフォームとして進化を続けています。特に、C/C++ライブラリのWasm化は以下のような利点があります。

  • SIMDやGC、例外処理などで性能と柔軟性が向上(最新のWasm仕様ベース)
  • WASI標準化の進展により、ブラウザ外でも同様のアプローチが可能
  • 既存の大規模ライブラリ資産を一から書き直す必要がなく、エコシステムを活用できる
  • Spiceシミュレータの内部構造や数値ライブラリ(KLU、SUNDIALSなど)も移植しやすい部類

もちろん、GUI機能やOS固有API、並列化、ライセンスなどを考慮する必要がありますが、総合的に見てC/C++ライブラリをWebAssemblyへ移植する成功率は高く、挑戦する価値は大いにあると言えます。自分もこれから挑戦してみようと思います。


参考リンク


以上

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?