におけるメモリモデル
10618 ワード
JavaScriptを実行するには、JavaScriptエンジンがリソースをダウンロードする必要があります.JavaScriptエンジンはリソースがダウンロードされるまで待ちます.ダウンロードしたら、JavaScriptエンジンを解析します.パーサーは、ソースコードをJavaScriptインタプリタが実行するバイトコードに変換します.
関数が複数回呼び出されるとき.The
関数をもっとたくさん呼び出すとき.コンパイラは関数をマークし、さらに最適化を試みます.この間
この関数は実行されます.最後に、コードはガベージコレクションです.
Javascriptエンジンは、webassemblyモジュールをダウンロードします.ダウンロードしたらwebassemblyモジュールをデコードします.
デコードされると、webassemblyモジュールがコンパイルされ、最適化されます.モジュールが既にコンパイルされて、最適化されているので、このステップは高速です.
モジュールが最終的に実行されます.
さびとwebassemblyの上で私の本をチェックしてくださいhere
webassembly実行を高速化する探索では、ブラウザのベンダーがストリーミングコンパイルを実装しました.webasemblyモジュールがまだダウンロード中の間、ストリーミングコンパイルはJavaScriptエンジンがモジュールをコンパイルして、最適化するのを可能にします.ファイルが完全にダウンロードされるまで、エンジンが待つべきJavaScriptと異なります.これはプロセスを高速化します.
JavaScriptとwebassemblyはブラウザレベルで2つの異なるものです.Javascriptまたはその逆のwebassemblyを呼び出すのは遅いです.(これはどんな2つの言語の間の呼び出しにも良いです).これは交差点の境界にコストがかかるためです.
ブラウザベンダー(特にFirefox)は、境界交差点のコストを削減しようとしています.実際には、Firefoxでは、JavascriptがWebassembly呼び出しをするのは、JavaScriptからJavaScriptまでの呼び出しに比べてずっと高速です.
しかし、アプリケーションを設計している間、適切な注意は境界交差点に与えられなければなりません.それらはアプリケーションの主要なパフォーマンスボトルネックになります.この場合、webassemblyモジュールのメモリモデルを理解することが重要です.
におけるメモリモデル
要素の再配置のための高い実行時間 多くの記憶領域を浪費する
メモリは解釈されていないデータの生のバイトのベクトルである.メモリの生のバイトを保持するために、変更可能な配列バッファを使用します.JavaScriptとweBassemblyは、メモリに対して同期的に読み書きできます.
メモリを割り当てることができます
webassemblyモジュール(Rustで書かれた)からJavaScriptにメモリを通して値を渡す方法を最初に見ましょう.
新しいプロジェクトを作成する
さびファイルは
機能
タイプの可変スライスを定義します
私たちは生のメモリにアクセスしているので、呼び出しを
最後に、我々は
JavaScriptでは、webassemblyモジュールを読み込み、モジュールからまっすぐアクセスします.
まず、webassemblyモジュールを取得し、インスタンス化します.
共有メモリは
私たちは、JavaScriptとwebassemblyの間でメモリを共有する方法を見ました.今はJavaScriptのメモリを作成し、錆の中でそれを使用する時間です.
JavaScriptランド内のメモリには、WebBassembly Landを割り当てる方法がありません.型として、webassembly明示的な型情報を期待します.webassembly landにどのようにメモリを割り当て、どのように解放するかを伝える必要があります.
JavaScript経由でメモリを作成するには、
メモリコンストラクターは、オブジェクトを既定値を設定します.それらは 初期-メモリの初期サイズ max -メモリの最大サイズ(任意) shared -共有メモリを使用するかどうかを示す 初期および最大の単位は( webassembly )ページです.各ページは64 KBまで保持します.
メモリを初期化します.
錆で
あなたがポストを楽しんだならば、あなたはさびとwebassemblyの上で私の本が好きかもしれません.チェックアウトhere
👇 レポ👇
Javascript APIを使用したwebassembly memoryhere
webassemblyのメモリアクセスはhere
もっとチェック
TypedArrayについてのチェックhere
//💻 GitHub // ✍️ Blog // 🔶 hackernews
閉じるこの動画はお気に入りから削除されています.❤️
関数が複数回呼び出されるとき.The
baseline compiler
( V 8で)コードをコンパイルします.コンパイルはメインスレッドで行われます.コンパイラはコンパイル時に時間を費やします.しかし、コンパイルされたコードは解釈されたコードより速く動きます.コンパイルされたコードはoptimising compiler
.関数をもっとたくさん呼び出すとき.コンパイラは関数をマークし、さらに最適化を試みます.この間
re-optimisation
, コンパイラは想定し、さらに最適化されたコードを生成します.この最適化は少し時間がかかりますが、生成されたコードははるかに高速です.この関数は実行されます.最後に、コードはガベージコレクションです.
WebAssembly is fast. 🚀
Javascriptエンジンは、webassemblyモジュールをダウンロードします.ダウンロードしたらwebassemblyモジュールをデコードします.
Decoding is faster than parsing.
デコードされると、webassemblyモジュールがコンパイルされ、最適化されます.モジュールが既にコンパイルされて、最適化されているので、このステップは高速です.
モジュールが最終的に実行されます.
Note: there is no separate garbage collection step. The WebAssembly module takes care of allocating and de-allocating the memory.
さびとwebassemblyの上で私の本をチェックしてくださいhere
webassembly実行を高速化する探索では、ブラウザのベンダーがストリーミングコンパイルを実装しました.webasemblyモジュールがまだダウンロード中の間、ストリーミングコンパイルはJavaScriptエンジンがモジュールをコンパイルして、最適化するのを可能にします.ファイルが完全にダウンロードされるまで、エンジンが待つべきJavaScriptと異なります.これはプロセスを高速化します.
JavaScriptとwebassemblyはブラウザレベルで2つの異なるものです.Javascriptまたはその逆のwebassemblyを呼び出すのは遅いです.(これはどんな2つの言語の間の呼び出しにも良いです).これは交差点の境界にコストがかかるためです.
ブラウザベンダー(特にFirefox)は、境界交差点のコストを削減しようとしています.実際には、Firefoxでは、JavascriptがWebassembly呼び出しをするのは、JavaScriptからJavaScriptまでの呼び出しに比べてずっと高速です.
しかし、アプリケーションを設計している間、適切な注意は境界交差点に与えられなければなりません.それらはアプリケーションの主要なパフォーマンスボトルネックになります.この場合、webassemblyモジュールのメモリモデルを理解することが重要です.
におけるメモリモデル
The memory section
webassemblyモジュールの線形メモリのベクトルです.
線形記憶モデル
A linear memory model is a memory addressing technique in which the memory is organized in a single contagious address space. It is also known as Flat memory model.
線形メモリモデルは、メモリを理解し、プログラムし、表現することを容易にする.
彼らは巨大な欠点がある
A linear memory model is a memory addressing technique in which the memory is organized in a single contagious address space. It is also known as Flat memory model.
メモリは解釈されていないデータの生のバイトのベクトルである.メモリの生のバイトを保持するために、変更可能な配列バッファを使用します.JavaScriptとweBassemblyは、メモリに対して同期的に読み書きできます.
メモリを割り当てることができます
WebAssembly.memory()
コンストラクタです.コードを書く✍️
webassemblyからJavaScriptへ
webassemblyモジュール(Rustで書かれた)からJavaScriptにメモリを通して値を渡す方法を最初に見ましょう.
新しいプロジェクトを作成する
cargo
.$ cargo new --lib memory_world
プロジェクトが正常に作成されたら.お気に入りのエディタでプロジェクトを開きます.編集しましょうsrc/lib.rs
下記の内容で#![no_std]
use core::panic::PanicInfo;
use core::slice::from_raw_parts_mut;
#[no_mangle]
fn memory_to_js() {
let obj: &mut [u8];
unsafe {
obj = from_raw_parts_mut::<u8>(0 as *mut u8, 1);
}
obj[0] = 13;
}
#[panic_handler]
fn panic(_info: &PanicInfo) -> !{
loop{}
}
これを加えるCargo.toml
:[lib]
crate-type = ["cdylib"]
何がある?
さびファイルは
#![no_std]
. The #![no_std]
属性はstd - crateの代わりに錆コンパイラをコアcrateに戻すように指示します.コア木箱はプラットフォーム不機嫌です.コアのcrateはstd crateの小さなサブセットです.これにより、バイナリサイズが劇的に減少します.機能
memory_to_js
に注釈付き#[no_mangle]
. この関数は、共有メモリ内の値を変更するため、値を返しません.タイプの可変スライスを定義します
u8
and name it as obj
. それから私たちはfrom_raw_parts_mut
作成するu8
ポインタと長さの使用.デフォルトでは0
我々はちょうど取る1
要素.私たちは生のメモリにアクセスしているので、呼び出しを
unsafe
ブロック.生成されたスライスfrom_raw_parts_mut
変更可能です.最後に、我々は
13
最初のインデックスで.unsafe {
obj = from_raw_parts_mut::<u8>(0 as *mut u8, 1);
}
obj[0] = 13;
また、apanic_handler
任意のパニックをキャプチャし、今のところそれを無視する(あなたの生産アプリケーションでこれをしないでください).Note that we are not using
wasm_bindgen
here.
JavaScriptでは、webassemblyモジュールを読み込み、モジュールからまっすぐアクセスします.
まず、webassemblyモジュールを取得し、インスタンス化します.
const bytes = await fetch("target/wasm32-unknown-unknown/debug/memory_world.wasm");
const response = await bytes.arrayBuffer();
const result = await WebAssembly.instantiate(response, {});
結果オブジェクトは、すべてのインポートされエクスポートされた関数を含むWebBassemblyオブジェクトです.エクスポートするmemory_to_js
関数からresult.exports
.result.exports.memory_to_js();
この関数はwebassembly modulememory_to_js
関数を共有し、共有メモリに値を代入する.共有メモリは
result.exports.memory.buffer
オブジェクト.const memObj = new UInt8Array(result.exports.memory.buffer, 0).slice(0, 1);
console.log(memObj[0]); // 13
メモリはload
and store
バイナリ命令.これらのバイナリ命令はoffset
とalignment
. The alignment
ベース2対数表現です.Note: WebAssembly currently provides only
32-bit
address ranges. In future, WebAssembly may provide64-bit
address range.
JavaScriptからwebassemblyへ
私たちは、JavaScriptとwebassemblyの間でメモリを共有する方法を見ました.今はJavaScriptのメモリを作成し、錆の中でそれを使用する時間です.
JavaScriptランド内のメモリには、WebBassembly Landを割り当てる方法がありません.型として、webassembly明示的な型情報を期待します.webassembly landにどのようにメモリを割り当て、どのように解放するかを伝える必要があります.
JavaScript経由でメモリを作成するには、
WebAssembly.Memory()
コンストラクタ.メモリコンストラクターは、オブジェクトを既定値を設定します.それらは
コードを書く✍️
メモリを初期化します.
const memory = new WebAssembly.Memory({initial: 10, maximum: 100});
メモリは初期化されるWebAssembly.Memory()
初期値のコンストラクタ10 pages
と最大値100 pages
. これはそれぞれ640 KBと6.4 MBの初期値と最大値に変換されます.const bytes = await fetch("target/wasm32-unknown-unknown/debug/memory_world.wasm");
const response = await bytes.arrayBuffer();
const instance = await WebAssembly.instantiate(response, { js: { mem: memory } });
webassemblyモジュールを取得し、インスタンス化します.しかし、インスタンス化する間、我々はメモリオブジェクトを通過します.const s = new Set([1, 2, 3]);
let jsArr = Uint8Array.from(s);
私たちはtypedArray
( UInt8Array
) 値1、2、3で.const len = jsArr.length;
let wasmArrPtr = instance.exports.malloc(length);
webassemblyモジュールには、メモリに作成されたオブジェクトのサイズについての手がかりがありません.webassemblyメモリを割り当てる必要があります.メモリの割り当てと解放を手動で書く必要があります.このステップでは、配列の長さを送信し、そのメモリを割り当てます.これはメモリの位置へのポインタを与える.let wasmArr = new Uint8Array(instance.exports.memory.buffer, wasmArrPtr, len);
それから、バッファ(合計利用可能なメモリ)、メモリオフセット(wasmattrptr)、およびメモリの長さを持つ新しいtypedarrayを作成します.wasmArr.set(jsArr);
最後に、ローカルに作成されたtypedarrayを設定します.jsArr
) を返します.wasmArrPtr
.const sum = instance.exports.accumulate(wasmArrPtr, len); // -> 7
console.log(sum);
私たちはpointer
とlength
を追加します.webassemblyモジュールでは、メモリから値を取得して使用します.錆で
malloc
and accumulate
関数は以下の通りである.use std::alloc::{alloc, dealloc, Layout};
use std::mem;
#[no_mangle]
fn malloc(size: usize) -> *mut u8 {
let align = std::mem::align_of::<usize>();
if let Ok(layout) = Layout::from_size_align(size, align) {
unsafe {
if layout.size() > 0 {
let ptr = alloc(layout);
if !ptr.is_null() {
return ptr
}
} else {
return align as *mut u8
}
}
}
std::process::abort
}
サイズを考えると、malloc関数はメモリブロックを割り当てます.#[no_mangle]
fn accumulate(data: *mut u8, len: usize) -> i32 {
let y = unsafe { std::slice::from_raw_parts(data as *const u8, len) };
let mut sum = 0;
for i in 0..len {
sum = sum + y[i];
}
sum as i32
}
累積関数は共有配列とサイズ( len )を取ります。そして、共有メモリからデータを復元する。その後、データを実行し、データ内のすべての要素の合計を返します。
あなたがポストを楽しんだならば、あなたはさびとwebassemblyの上で私の本が好きかもしれません.チェックアウトhere
👇 レポ👇
センディルマル / Rustwasmメモリモデル
WebBassemblyとJavaScriptの間でメモリを共有する
探検する興味
Javascript APIを使用したwebassembly memoryhere
webassemblyのメモリアクセスはhere
もっとチェック
from_raw_parts_mut
アットhere TypedArrayについてのチェックhere
//💻 GitHub // ✍️ Blog // 🔶 hackernews
閉じるこの動画はお気に入りから削除されています.❤️
Reference
この問題について(におけるメモリモデル), 我々は、より多くの情報をここで見つけました https://dev.to/sendilkumarn/rust-and-webassembly-for-the-masses-memory-model-1jhdテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol