1) (data (i32.const 8) '1e000100010001e000~0l0i0b0/0r0t0/0t0l0s0f0.0t0s0') ... ;; Our global constants (not yet exported) (global $nBodyForces/FLOAT64ARRAY_ID i32 (i32.const 3)) (global $nBodyForces/G f64 (f64.const 6.674e-11)) (global $nBodyForces/bodySize i32 (i32.const 4)) (global $nBodyForces/forceSize i32 (i32.const 3)) ... ;; Memory management functions we’ll use in a minute (export 'memory' (memory

WebVR Μέρος 3: Ξεκλείδωμα του δυναμικού WebAss Assembly και AssemblyScript



Το WebAss Assembly είναι σίγουρα δεν μια αντικατάσταση του JavaScript ως το lingua franca του ιστού και του κόσμου.

Το WebAssembly (συντομογραφία Wasm) είναι μια μορφή δυαδικής εντολής για μια εικονική μηχανή που βασίζεται σε στοίβα. Το Wasm έχει σχεδιαστεί ως φορητός στόχος για τη συλλογή γλωσσών υψηλού επιπέδου όπως C / C ++ / Rust, επιτρέποντας την ανάπτυξη στον ιστό για εφαρμογές πελατών και διακομιστών. ' - WebAssembly.org



Είναι σημαντικό να διακρίνουμε ότι το WebAss Assembly δεν είναι γλώσσα. Το WebAssembly είναι σαν ένα αρχείο .exe - ή ακόμα καλύτερα - ένα αρχείο Java .class. Συντάσσεται από τον προγραμματιστή ιστού από άλλη γλώσσα, στη συνέχεια κατεβάζεται και εκτελείται στο πρόγραμμα περιήγησής σας.



Το WebAss Assembly παρέχει JavaScript σε όλες τις δυνατότητες που περιστασιακά θέλαμε να δανειζόμαστε αλλά ποτέ Πραγματικά ήθελε να κατέχει. Όπως και η ενοικίαση βάρκας ή αλόγου, το WebAss Assembly μας επιτρέπει να ταξιδεύουμε σε άλλες γλώσσες χωρίς να χρειάζεται να κάνουμε υπερβολικές επιλογές «γλωσσικού τρόπου ζωής». Αυτό επέτρεψε στον Ιστό να επικεντρωθεί σε σημαντικά πράγματα, όπως η παροχή λειτουργιών και η βελτίωση της εμπειρίας των χρηστών.



Περισσότερες από 20 γλώσσες μεταγλώττισης στο WebAss Assembly: Rust, C / C ++, C # /. Net, Java, Python, Elixir, Go και φυσικά JavaScript.

Αν θυμάστε το διάγραμμα αρχιτεκτονικής της προσομοίωσης, αναθέσαμε ολόκληρη την προσομοίωση στο nBodySimulator, οπότε διαχειρίζεται το web worker.



Διάγραμμα αρχιτεκτονικής προσομοίωσης

Σχήμα 1: Συνολική αρχιτεκτονική.

Εάν θυμάστε από το εισαγωγική δημοσίευση , nBodySimulator έχει ένα step() συνάρτηση που ονομάζεται κάθε 33ms. Το step() Η λειτουργία κάνει αυτά τα πράγματα - αριθμημένα στο παραπάνω διάγραμμα:



  1. nBodySimulator's calculateForces() κλήσεις this.worker.postMessage() για να ξεκινήσετε τον υπολογισμό.
  2. workerWasm.js this.onmessage() παίρνει το μήνυμα.
  3. Ο εργαζόμενοςWasm.js εκτελεί συγχρονισμένα το nBodyForces.wasm's nBodyForces() λειτουργία.
  4. workerWasm.js απαντήσεις χρησιμοποιώντας this.postMessage() στο κύριο νήμα με τις νέες δυνάμεις.
  5. Το κύριο νήμα this.worker.onMessage() marshals τα επιστρεφόμενα δεδομένα και κλήσεις.
  6. nBodySimulator's applyForces() για ενημέρωση των θέσεων των οργάνων.
  7. Τέλος, ο οπτικοποιητής βάφει ξανά.

Νήμα διεπαφής χρήστη, νήμα εργαζόμενου ιστού

Εικόνα 2: Μέσα στη λειτουργία βήματος () του προσομοιωτή

Σε την προηγούμενη ανάρτηση , δημιουργήσαμε το web worker που τυλίγει τους υπολογισμούς WASM. Σήμερα, χτίζουμε το μικροσκοπικό κουτί με την ένδειξη 'WASM' και μεταφέρουμε δεδομένα μέσα και έξω.



Για απλότητα, επέλεξα Σενάριο ως γλώσσα πηγαίου κώδικα για να γράψουμε τους υπολογισμούς μας. Το AssemblyScript είναι ένα υποσύνολο του TypeScript - το οποίο είναι πληκτρολογημένο JavaScript - έτσι το γνωρίζετε ήδη.

Για παράδειγμα, αυτή η συνάρτηση AssemblyScript υπολογίζει τη βαρύτητα μεταξύ δύο σωμάτων: Το :f64 σε someVar:f64 επισημαίνει τη μεταβλητή someVar ως float για τον μεταγλωττιστή. Θυμηθείτε ότι αυτός ο κωδικός έχει συνταχθεί και εκτελεστεί σε εντελώς διαφορετικό χρόνο εκτέλεσης από το JavaScript.



// AssemblyScript - a TypeScript-like language that compiles to WebAssembly // src/assembly/nBodyForces.ts /** * Given two bodies, calculate the Force of Gravity, * then return as a 3-force vector (x, y, z) * * Sometimes, the force of gravity is: * * Fg = G * mA * mB / r^2 * * Given: * - Fg = Force of gravity * - r = sqrt ( dx + dy + dz) = straight line distance between 3d objects * - G = gravitational constant * - mA, mB = mass of objects * * Today, we're using better-gravity because better-gravity can calculate * force vectors without polar math (sin, cos, tan) * * Fbg = G * mA * mB * dr / r^3 // using dr as a 3-distance vector lets * // us project Fbg as a 3-force vector * * Given: * - Fbg = Force of better gravity * - dr = (dx, dy, dz) // a 3-distance vector * - dx = bodyB.x - bodyA.x * * Force of Better-Gravity: * * - Fbg = (Fx, Fy, Fz) = the change in force applied by gravity each * body's (x,y,z) over this time period * - Fbg = G * mA * mB * dr / r^3 * - dr = (dx, dy, dz) * - Fx = Gmm * dx / r3 * - Fy = Gmm * dy / r3 * - Fz = Gmm * dz / r3 * * From the parameters, return an array [fx, fy, fz] */ function twoBodyForces(xA: f64, yA: f64, zA: f64, mA: f64, xB: f64, yB: f64, zB: f64, mB: f64): f64[]

Αυτή η συνάρτηση AssemblyScript παίρνει το (x, y, z, mass) για δύο σώματα και επιστρέφει μια σειρά από τρία επιπλέοντα που περιγράφουν το (x, y, z) διανύσματος δύναμης που τα σώματα εφαρμόζουν το ένα στο άλλο. Δεν μπορούμε να καλέσουμε αυτήν τη λειτουργία από το JavaScript επειδή το JavaScript δεν έχει ιδέα πού να το βρει. Πρέπει να το 'εξαγάγουμε' σε JavaScript. Αυτό μας φέρνει στην πρώτη τεχνική πρόκληση.

Εισαγωγές και εξαγωγές WebAss Assembly

Στο ES6, σκεφτόμαστε τις εισαγωγές και τις εξαγωγές σε κώδικα JavaScript και χρησιμοποιούμε εργαλεία όπως το Rollup ή το Webpack για να δημιουργήσουμε κώδικα που τρέχει σε προγράμματα περιήγησης παλαιού τύπου για να χειριστεί import και require(). Αυτό δημιουργεί ένα δέντρο εξάρτησης από πάνω προς τα κάτω και επιτρέπει τη δροσερή τεχνολογία όπως ' κούνημα των δέντρων ' και διαχωρισμός κώδικα .



Στο WebAss Assembly, οι εισαγωγές και οι εξαγωγές εκτελούν διαφορετικές εργασίες από μια εισαγωγή ES6. Εισαγωγές / εξαγωγές WebAss Assembly:

Στον παρακάτω κώδικα, env.abort και env.trace αποτελούν μέρος του περιβάλλοντος που πρέπει να παρέχουμε στη λειτουργική μονάδα WebAss Assembly. Το nBodyForces.logI και οι λειτουργίες φίλων παρέχουν μηνύματα εντοπισμού σφαλμάτων στην κονσόλα. Σημειώστε ότι η παράδοση συμβολοσειρών εισόδου / εξόδου από το WebAssembly δεν είναι ασήμαντη, καθώς οι μόνοι τύποι WebAssembly είναι αριθμοί i32, i64, f32, f64, με αναφορές i32 σε μια αφηρημένη γραμμική μνήμη.

Σημείωση: Αυτά τα παραδείγματα κώδικα εναλλάσσονται μεταξύ κώδικα JavaScript (ο εργαζόμενος στο web) και AssemblyScript (ο κωδικός WASM).

// Web Worker JavaScript in workerWasm.js /** * When we instantiate the Wasm module, give it a context to work in: * nBodyForces: {} is a table of functions we can import into AssemblyScript. See top of nBodyForces.ts * env: {} describes the environment sent to the Wasm module as it's instantiated */ const importObj = { nBodyForces: { logI(data) { console.log('Log() - ' + data); }, logF(data) { console.log('Log() - ' + data); }, }, env: { abort(msg, file, line, column) { // wasm.__getString() is added by assemblyscript's loader: // https://github.com/AssemblyScript/assemblyscript/tree/master/lib/loader console.error('abort: (' + wasm.__getString(msg) + ') at ' + wasm.__getString(file) + ':' + line + ':' + column); }, trace(msg, n) { console.log('trace: ' + wasm.__getString(msg) + (n ? ' ' : '') + Array.prototype.slice.call(arguments, 2, 2 + n).join(', ')); } } }

Στον κώδικα AssemblyScript, μπορούμε να ολοκληρώσουμε την εισαγωγή αυτών των λειτουργιών όπως:

// nBodyForces.ts declare function logI(data: i32): void declare function logF(data: f64): void

Σημείωση : Η ματαίωση και το ίχνος εισάγονται αυτόματα .

Από το AssemblyScript, μπορούμε να εξάγουμε τη διεπαφή μας. Ακολουθούν ορισμένες εξαγόμενες σταθερές:

// src/assembly/nBodyForces.ts // Gravitational constant. Any G could be used in a game. // This value is best for a scientific simulation. export const G: f64 = 6.674e-11; // for sizing and indexing arrays export const bodySize: i32 = 4 export const forceSize: i32 = 3

Και εδώ είναι η εξαγωγή nBodyForces() το οποίο θα καλέσουμε από το JavaScript. Εξάγουμε τον τύπο Float64Array στο πάνω μέρος του αρχείου, ώστε να μπορούμε να χρησιμοποιήσουμε το πρόγραμμα φόρτωσης JavaScript του AssemblyScript στον web εργαζόμενο για να λάβουμε τα δεδομένα (δείτε παρακάτω):

// src/assembly/nBodyForces.ts export const FLOAT64ARRAY_ID = idof(); ... /** * Given N bodies with mass, in a 3d space, calculate the forces of gravity to be applied to each body. * * This function is exported to JavaScript, so only takes/returns numbers and arrays. * For N bodies, pass and array of 4N values (x,y,z,mass) and expect a 3N array of forces (x,y,z) * Those forces can be applied to the bodies mass to update its position in the simulation. * Calculate the 3-vector each unique pair of bodies applies to each other. * * 0 1 2 3 4 5 * 0 x x x x x * 1 x x x x * 2 x x x * 3 x x * 4 x * 5 * * Sum those forces together into an array of 3-vector x,y,z forces * * Return 0 on success */ export function nBodyForces(arrBodies: Float64Array): Float64Array { // Check inputs const numBodies: i32 = arrBodies.length / bodySize if (arrBodies.length % bodySize !== 0) trace('INVALID nBodyForces parameter. Chaos ensues...') // Create result array. This should be garbage collected later. let arrForces: Float64Array = new Float64Array(numBodies * forceSize) // For all bodies: for (let i: i32 = 0; i i for (let j: i32 = i + 1; j

Τεχνητά αντικείμενα WebAss Assembly: .wasm και .wat

Όταν το AssemblyScript μας nBodyForces.ts μεταγλωττίζεται σε WebAss Assembly nBodyForces.wasm δυάδικος , υπάρχει η επιλογή να δημιουργήσετε επίσης μια έκδοση 'κειμένου' που περιγράφει τις οδηγίες στο δυαδικό.

Τεχνητά αντικείμενα WebAss Assembly

Εικόνα 3: Θυμηθείτε, το AssemblyScript είναι μια γλώσσα. Το WebAssembly είναι ένας μεταγλωττιστής και χρόνος εκτέλεσης.

Μέσα στο nBodyForces.wat αρχείο, μπορούμε να δούμε αυτές τις εισαγωγές και εξαγωγές:

;; This is a comment in nBodyForces.wat (module ;; compiler defined types (type $FUNCSIG$iii (func (param i32 i32) (result i32))) … ;; Expected imports from JavaScript (import 'env' 'abort' (func $~lib/builtins/abort (param i32 i32 i32 i32))) (import 'env' 'trace' (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64))) ;; Memory section defining data constants like strings (memory $0 1) (data (i32.const 8) '1e000100010001e000~0l0i0b0/0r0t0/0t0l0s0f0.0t0s0') ... ;; Our global constants (not yet exported) (global $nBodyForces/FLOAT64ARRAY_ID i32 (i32.const 3)) (global $nBodyForces/G f64 (f64.const 6.674e-11)) (global $nBodyForces/bodySize i32 (i32.const 4)) (global $nBodyForces/forceSize i32 (i32.const 3)) ... ;; Memory management functions we’ll use in a minute (export 'memory' (memory $0)) (export '__alloc' (func $~lib/rt/tlsf/__alloc)) (export '__retain' (func $~lib/rt/pure/__retain)) (export '__release' (func $~lib/rt/pure/__release)) (export '__collect' (func $~lib/rt/pure/__collect)) (export '__rtti_base' (global $~lib/rt/__rtti_base)) ;; Finally our exported constants and function (export 'FLOAT64ARRAY_ID' (global $nBodyForces/FLOAT64ARRAY_ID)) (export 'G' (global $nBodyForces/G)) (export 'bodySize' (global $nBodyForces/bodySize)) (export 'forceSize' (global $nBodyForces/forceSize)) (export 'nBodyForces' (func $nBodyForces/nBodyForces)) ;; Implementation details ...

Έχουμε τώρα το nBodyForces.wasm δυαδικό και ένα web worker για να το εκτελέσετε. Ετοιμαστείτε για έκρηξη! Και κάποια διαχείριση μνήμης!

Για να ολοκληρώσουμε την ενσωμάτωση, πρέπει να περάσουμε μια μεταβλητή συστοιχία πλωτών στο WebAssembly και να επιστρέψουμε μια μεταβλητή σειρά πλωτή στο JavaScript.

Με την αφελής αστική JavaScript, ξεκίνησα να περνάω απλώς αυτές τις φανταστικές συστοιχίες μεταβλητού μεγέθους μέσα και έξω από έναν χρόνο εκτέλεσης υψηλής απόδοσης πολλαπλών πλατφορμών. Η διαβίβαση δεδομένων από / προς το WebAssembly ήταν, μακράν, η πιο απροσδόκητη δυσκολία σε αυτό το έργο.

Ωστόσο, με πολλές ευχαριστίες για το βαριά ανύψωση έγινε από την ομάδα AssemblyScript , μπορούμε να χρησιμοποιήσουμε το 'φορτωτή' τους για να βοηθήσουμε:

// workerWasm.js - our web worker /** * AssemblyScript loader adds helpers for moving data to/from AssemblyScript. * Highly recommended */ const loader = require('assemblyscript/lib/loader')

Το require() σημαίνει ότι πρέπει να χρησιμοποιήσουμε ένα πρόγραμμα δέσμης στοιχείων όπως το Rollup ή το Webpack. Για αυτό το έργο, επέλεξα το Rollup για την απλότητα και την ευελιξία του και δεν κοίταξα ποτέ πίσω.

Θυμηθείτε ότι ο εργαζόμενος στο Διαδίκτυο λειτουργεί σε ξεχωριστό νήμα και είναι ουσιαστικά ένα onmessage() συνάρτηση με switch() δήλωση.

loader δημιουργεί τη λειτουργική μονάδα μας με μερικές επιπλέον εύχρηστες λειτουργίες διαχείρισης μνήμης. __retain() και __release() διαχείριση αναφορών συλλογής απορριμμάτων στο χρόνο εκτέλεσης εργαζομένων __allocArray() αντιγράφει τον πίνακα παραμέτρων στη μνήμη της μονάδας wasm __getFloat64Array() αντιγράφει τον πίνακα αποτελεσμάτων από τη λειτουργική μονάδα wasm στο χρόνο εκτέλεσης εργαζομένων

Μπορούμε τώρα να στρατολογήσουμε συστοιχίες επιπλέουν μέσα και έξω από nBodyForces() και ολοκληρώστε την προσομοίωσή μας:

// workerWasm.js /** * Web workers listen for messages from the main thread. */ this.onmessage = function (evt) { // message from UI thread var msg = evt.data switch (msg.purpose) { // Message: Load new wasm module case 'wasmModule': // Instantiate the compiled module we were passed. wasm = loader.instantiate(msg.wasmModule, importObj) // Throws // Tell nBodySimulation.js we are ready this.postMessage({ purpose: 'wasmReady' }) return // Message: Given array of floats describing a system of bodies (x,y,x,mass), // calculate the Grav forces to be applied to each body case 'nBodyForces': if (!wasm) throw new Error('wasm not initialized') // Copy msg.arrBodies array into the wasm instance, increase GC count const dataRef = wasm.__retain(wasm.__allocArray(wasm.FLOAT64ARRAY_ID, msg.arrBodies)); // Do the calculations in this thread synchronously const resultRef = wasm.nBodyForces(dataRef); // Copy result array from the wasm instance to our javascript runtime const arrForces = wasm.__getFloat64Array(resultRef); // Decrease the GC count on dataRef from __retain() here, // and GC count from new Float64Array in wasm module wasm.__release(dataRef); wasm.__release(resultRef); // Message results back to main thread. // see nBodySimulation.js this.worker.onmessage return this.postMessage({ purpose: 'nBodyForces', arrForces }) } }

Με όλα όσα μάθαμε, ας ρίξουμε μια ματιά στο ταξίδι του Web Worker και του WebAss Assembly. Καλώς ήλθατε στο νέο πρόγραμμα περιήγησης του ιστού. Αυτοί είναι σύνδεσμοι προς τον κώδικα στο GitHub:

  1. GET Index.html
  2. main.js
  3. nBodySimulator.js - μεταβιβάζει ένα μήνυμα στον εργαζόμενο του διαδικτύου
  4. εργαζόμενος Wasm.js - καλεί τη λειτουργία WebAss Assembly
  5. nBodyForces.ts - υπολογίζει και επιστρέφει μια σειρά δυνάμεων
  6. εργαζόμενος Wasm.js - μεταφέρει τα αποτελέσματα πίσω στο κύριο νήμα
  7. nBodySimulator.js - επιλύει την υπόσχεση για δυνάμεις
  8. nBodySimulator.js - στη συνέχεια εφαρμόζει τις δυνάμεις στα σώματα και λέει στους οπτικοποιητές να ζωγραφίσουν

Από εδώ, ας ξεκινήσουμε την παράσταση δημιουργώντας nBodyVisualizer.js! Η επόμενη ανάρτησή μας δημιουργεί έναν οπτικοποιητή χρησιμοποιώντας το Canvas API και η τελική ανάρτηση ολοκληρώνεται με WebVR και Aframe.

Σχετίζεται με: WebAssembly / Rust Tutorial: Επεξεργασία ήχου τέλειου βήματος

Κατανόηση των βασικών

Μπορεί το WebAss Assembly να αντικαταστήσει τη JavaScript;

Το WebAss Assembly δεν είναι γλώσσα, επομένως δεν μπορεί να αντικαταστήσει τη JavaScript. Επίσης, η ανάπτυξη λειτουργιών και εμπειρίας χρήστη στο WebAssembly είναι λιγότερο αποτελεσματική.

Γιατί είναι πιο γρήγορη η WebAss Assembly;

Το WebAss Assembly είναι ταχύτερο επειδή κάνει λιγότερα και σχεδιάστηκε για απόδοση αντί για χρηστικότητα προγραμματιστή.

Μπορεί το JavaScript να μεταγλωττιστεί στο WebAss Assembly;

Ναι, το AssemblyScript μεταγλωττίζεται στο WebAss Assembly και μοιάζει με Typescript.

)) (export '__alloc' (func $~lib/rt/tlsf/__alloc)) (export '__retain' (func $~lib/rt/pure/__retain)) (export '__release' (func $~lib/rt/pure/__release)) (export '__collect' (func $~lib/rt/pure/__collect)) (export '__rtti_base' (global $~lib/rt/__rtti_base)) ;; Finally our exported constants and function (export 'FLOAT64ARRAY_ID' (global $nBodyForces/FLOAT64ARRAY_ID)) (export 'G' (global $nBodyForces/G)) (export 'bodySize' (global $nBodyForces/bodySize)) (export 'forceSize' (global $nBodyForces/forceSize)) (export 'nBodyForces' (func $nBodyForces/nBodyForces)) ;; Implementation details ...

Έχουμε τώρα το nBodyForces.wasm δυαδικό και ένα web worker για να το εκτελέσετε. Ετοιμαστείτε για έκρηξη! Και κάποια διαχείριση μνήμης!

Για να ολοκληρώσουμε την ενσωμάτωση, πρέπει να περάσουμε μια μεταβλητή συστοιχία πλωτών στο WebAssembly και να επιστρέψουμε μια μεταβλητή σειρά πλωτή στο JavaScript.

Με την αφελής αστική JavaScript, ξεκίνησα να περνάω απλώς αυτές τις φανταστικές συστοιχίες μεταβλητού μεγέθους μέσα και έξω από έναν χρόνο εκτέλεσης υψηλής απόδοσης πολλαπλών πλατφορμών. Η διαβίβαση δεδομένων από / προς το WebAssembly ήταν, μακράν, η πιο απροσδόκητη δυσκολία σε αυτό το έργο.

Ωστόσο, με πολλές ευχαριστίες για το βαριά ανύψωση έγινε από την ομάδα AssemblyScript , μπορούμε να χρησιμοποιήσουμε το 'φορτωτή' τους για να βοηθήσουμε:

πώς να φτιάξετε μια γλώσσα προγραμματισμού σε c++
// workerWasm.js - our web worker /** * AssemblyScript loader adds helpers for moving data to/from AssemblyScript. * Highly recommended */ const loader = require('assemblyscript/lib/loader')

Το require() σημαίνει ότι πρέπει να χρησιμοποιήσουμε ένα πρόγραμμα δέσμης στοιχείων όπως το Rollup ή το Webpack. Για αυτό το έργο, επέλεξα το Rollup για την απλότητα και την ευελιξία του και δεν κοίταξα ποτέ πίσω.

Θυμηθείτε ότι ο εργαζόμενος στο Διαδίκτυο λειτουργεί σε ξεχωριστό νήμα και είναι ουσιαστικά ένα onmessage() συνάρτηση με switch() δήλωση.

loader δημιουργεί τη λειτουργική μονάδα μας με μερικές επιπλέον εύχρηστες λειτουργίες διαχείρισης μνήμης. __retain() και __release() διαχείριση αναφορών συλλογής απορριμμάτων στο χρόνο εκτέλεσης εργαζομένων __allocArray() αντιγράφει τον πίνακα παραμέτρων στη μνήμη της μονάδας wasm __getFloat64Array() αντιγράφει τον πίνακα αποτελεσμάτων από τη λειτουργική μονάδα wasm στο χρόνο εκτέλεσης εργαζομένων

πώς να χρησιμοποιήσετε το power pivot

Μπορούμε τώρα να στρατολογήσουμε συστοιχίες επιπλέουν μέσα και έξω από nBodyForces() και ολοκληρώστε την προσομοίωσή μας:

// workerWasm.js /** * Web workers listen for messages from the main thread. */ this.onmessage = function (evt) { // message from UI thread var msg = evt.data switch (msg.purpose) { // Message: Load new wasm module case 'wasmModule': // Instantiate the compiled module we were passed. wasm = loader.instantiate(msg.wasmModule, importObj) // Throws // Tell nBodySimulation.js we are ready this.postMessage({ purpose: 'wasmReady' }) return // Message: Given array of floats describing a system of bodies (x,y,x,mass), // calculate the Grav forces to be applied to each body case 'nBodyForces': if (!wasm) throw new Error('wasm not initialized') // Copy msg.arrBodies array into the wasm instance, increase GC count const dataRef = wasm.__retain(wasm.__allocArray(wasm.FLOAT64ARRAY_ID, msg.arrBodies)); // Do the calculations in this thread synchronously const resultRef = wasm.nBodyForces(dataRef); // Copy result array from the wasm instance to our javascript runtime const arrForces = wasm.__getFloat64Array(resultRef); // Decrease the GC count on dataRef from __retain() here, // and GC count from new Float64Array in wasm module wasm.__release(dataRef); wasm.__release(resultRef); // Message results back to main thread. // see nBodySimulation.js this.worker.onmessage return this.postMessage({ purpose: 'nBodyForces', arrForces }) } }

Με όλα όσα μάθαμε, ας ρίξουμε μια ματιά στο ταξίδι του Web Worker και του WebAss Assembly. Καλώς ήλθατε στο νέο πρόγραμμα περιήγησης του ιστού. Αυτοί είναι σύνδεσμοι προς τον κώδικα στο GitHub:

  1. GET Index.html
  2. main.js
  3. nBodySimulator.js - μεταβιβάζει ένα μήνυμα στον εργαζόμενο του διαδικτύου
  4. εργαζόμενος Wasm.js - καλεί τη λειτουργία WebAss Assembly
  5. nBodyForces.ts - υπολογίζει και επιστρέφει μια σειρά δυνάμεων
  6. εργαζόμενος Wasm.js - μεταφέρει τα αποτελέσματα πίσω στο κύριο νήμα
  7. nBodySimulator.js - επιλύει την υπόσχεση για δυνάμεις
  8. nBodySimulator.js - στη συνέχεια εφαρμόζει τις δυνάμεις στα σώματα και λέει στους οπτικοποιητές να ζωγραφίσουν

Από εδώ, ας ξεκινήσουμε την παράσταση δημιουργώντας nBodyVisualizer.js! Η επόμενη ανάρτησή μας δημιουργεί έναν οπτικοποιητή χρησιμοποιώντας το Canvas API και η τελική ανάρτηση ολοκληρώνεται με WebVR και Aframe.

Σχετίζεται με: WebAssembly / Rust Tutorial: Επεξεργασία ήχου τέλειου βήματος

Κατανόηση των βασικών

Μπορεί το WebAss Assembly να αντικαταστήσει τη JavaScript;

Το WebAss Assembly δεν είναι γλώσσα, επομένως δεν μπορεί να αντικαταστήσει τη JavaScript. Επίσης, η ανάπτυξη λειτουργιών και εμπειρίας χρήστη στο WebAssembly είναι λιγότερο αποτελεσματική.

Γιατί είναι πιο γρήγορη η WebAss Assembly;

Το WebAss Assembly είναι ταχύτερο επειδή κάνει λιγότερα και σχεδιάστηκε για απόδοση αντί για χρηστικότητα προγραμματιστή.

Μπορεί το JavaScript να μεταγλωττιστεί στο WebAss Assembly;

Ναι, το AssemblyScript μεταγλωττίζεται στο WebAss Assembly και μοιάζει με Typescript.