Mozilla Hacksの「A cartoon intro to ArrayBuffers and SharedArrayBuffers」を読みました。SharedArrayBufferとAtomicsを扱う3本シリーズの第2回で、ArrayBufferがJavaScriptにどのような低レベルメモリ操作の入口を与え、SharedArrayBufferがそれをworker間の共有メモリへ広げるのかを説明しています。
前回紹介したAtomicsの記事は、共有メモリを使ったときの壊れ方をどう防ぐかの話でした。今回の記事は、その一つ手前にある「そもそもArrayBufferとSharedArrayBufferは何を可能にするのか」を整理する内容です。
記事の要点
- JavaScriptは通常、自動メモリ管理を備えた言語ですが、ArrayBufferを使うと一部のデータをより低レベルに扱えます。
- ArrayBuffer自体は、0と1が並んだ生のメモリ領域のようなものです。
- ArrayBufferを直接読むのではなく、Int8ArrayやUint16Arrayなどのtyped array viewを通じて、同じbit列をどの単位で解釈するかを決めます。
- 同じArrayBufferに複数のviewを重ねると、同じbit列でも異なる数値として扱えます。
- Web Workerを使うとJavaScriptの処理をmain threadから分けられますが、通常はmemoryを共有せず、postMessageでデータをコピーします。
- ArrayBufferはtransferにより、コピーではなく所有権を移すことができます。ただし移した後は元のworkerから使えません。
- SharedArrayBufferは、複数のworkerが同じmemory blockを同時に読み書きできるようにします。
- その代わり、同時アクセスによるrace conditionが起きるため、次の記事で扱われるAtomicsが必要になります。
リンク先も見てわかったこと
シリーズ第1回の「A crash course in memory management」では、JavaScriptの自動メモリ管理と、Cのような手動メモリ管理の違いが説明されています。ArrayBuffer記事は、その前提の上に「JavaScriptでも必要な場面ではより低レベルなメモリ表現を扱える」という位置づけです。
MDNのArrayBufferとSharedArrayBufferページも確認しました。特にSharedArrayBufferについては、2017年記事のステータス説明をそのまま現在情報として読むのではなく、現在はSpectre以降のセキュリティ要件としてsecure contextとcross-origin isolatedが必要になる点を押さえておく必要があります。
Web WorkersとWorker.postMessage()のMDNページも、この記事の背景を理解するのに役立ちます。postMessageはworker間通信の基本ですが、大きなデータをコピーするコストが課題になります。ArrayBufferのtransferとSharedArrayBufferの共有は、そのコストをどう避けるかという文脈で出てきます。
気づき
今回の気づきは、SharedArrayBufferは「速くするAPI」というより、「コピーしないで済む代わりに、責任を開発者側へ戻すAPI」だという点です。通常のJavaScriptでは、メモリの割り当てや解放、worker間のデータ隔離はエンジンやプラットフォームがかなり面倒を見てくれます。SharedArrayBufferは、その保護を一部ゆるめることで、より低レベルで高速な協調処理を可能にします。
ただし、共有メモリは便利さと危険がセットです。コピーやtransferなら所有者が比較的はっきりしていますが、SharedArrayBufferでは複数のworkerが同じ場所を同時に見るため、読み書きの順序を考えなければなりません。だから次の記事でAtomicsが必要になる。ArrayBuffer、SharedArrayBuffer、Atomicsは、低レベル化の階段として読むと流れがかなりわかりやすくなります。
また、2017年当時の記事と現在のMDNを見比べると、Webの低レベル機能は性能だけで決まらないことも見えます。Shared memoryはWebAssemblyのthreadsにもつながる重要な基盤ですが、Spectre以降はセキュリティ境界とセットで扱う必要があります。低レベル機能ほど、性能、使いやすさ、安全性の三つを同時に設計しないといけないのだと感じました。
読むとよさそうな人
- ArrayBufferとTypedArrayの関係をざっくり理解したい人
- Web WorkerのpostMessage、transfer、shared memoryの違いを整理したい人
- SharedArrayBufferとAtomicsがなぜセットで語られるのか知りたい人

コメントを残す