From 55c652137a5e83f2eec918f1c31fbecf84ac5129 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Thu, 7 Jul 2022 14:22:27 +0300 Subject: [PATCH 1/4] update n-body --- n-body/README.md | 15 ++++++----- n-body/asconfig.json | 17 ++++++++++++ n-body/build/as_nbody.wasm | Bin 1785 -> 1829 bytes n-body/package.json | 9 +++---- n-body/scripts/postprocess-js.js | 8 ------ n-body/scripts/postprocess.js | 8 ++++++ n-body/tests/index.js | 43 ++++++------------------------- 7 files changed, 45 insertions(+), 55 deletions(-) create mode 100644 n-body/asconfig.json delete mode 100644 n-body/scripts/postprocess-js.js create mode 100644 n-body/scripts/postprocess.js diff --git a/n-body/README.md b/n-body/README.md index f3d370b..897cede 100644 --- a/n-body/README.md +++ b/n-body/README.md @@ -28,26 +28,27 @@ to start a local server. To run the benchmark: -``` +```bash $> npm test [steps=1000000] ``` Benchmark + ========= ***Environment:*** + - MacBook Pro (15-inch, 2019) -- macOS 10.15.3 -- node.js v13.8.0 +- macOS 12.4.0 +- node.js v18.4.0 - rustc 1.42.0-nightly (3a3f4a7cb 2019-12-28) ***Results:*** | Target | Time, ***ms*** | Size, ***KB*** | |-------------------------|-----------------|----------------| -| **AssemblyScript WASM** | **1602** | **1.6** | -| AssemblyScript ASMJS | 2368 | 10* | -| JavaScript | 1616 | 5* | -| Rust WASM | 1618 | 2 | +| **AssemblyScript WASM** | **1599** | **1.8** | +| JavaScript | 11608 | 5* | +| Rust WASM | 1631 | 2 | ___* unminified___ diff --git a/n-body/asconfig.json b/n-body/asconfig.json new file mode 100644 index 0000000..89e7879 --- /dev/null +++ b/n-body/asconfig.json @@ -0,0 +1,17 @@ +{ + "options": { + "runtime": "stub", + "importMemory": true, + "sourceMap": true + }, + "targets": { + "wasm": { + "outFile": "build/as_nbody.wasm", + "textFile": "build/as_nbody.wat", + "optimizeLevel": 3, + "shrinkLevel": 0, + "converge": true, + "noAssert": true + } + } +} diff --git a/n-body/build/as_nbody.wasm b/n-body/build/as_nbody.wasm index ed27e75dc1d6b1dfae031c3ab9ad54ddac89c5d6..ab5b4616ac7156eec2b3821cca0d6feae30675ed 100644 GIT binary patch delta 1096 zcmYjQO-~b16n!7_)tMHCKw<+f?hF_vA;GRlNK`rz;s=@-6E|+8C^43lmJcy#lVQOR zkaXpWc8FX5fku~_xbP1sF8v3(5zl>v*h%`{J?Fi5-+AZW{wcj3dOcoMSthd;x845` z3fW$f;M9cDYa6?EZMC_zBTVcx)*8*NJtd?rc-j)umd@eBt9DT;|J&i4X=xpP8qaiU z)ni3gI$BR#o2j)P1KSHCcG7Ss9cD6im#r!}WRts|o}TJ@y1(DvOvByS1?%3PsESnF z#1{7~5J3=-Jtaw#HKznAPODQfrz|p)hZQ-eilkiv8T>$f2 zE@8Z;cswxU7qy&0FekRsvGqiSsoIUSu96_lGAt6Q+Nmc>#BxSgA{#0Zl*!J!5d<2k`_hNcSKeR$cs!2;f?PvnXAFVy2Dc=nrbO^pDLX5+ zNpO+@jW#rDvTqrUdO)LyimbznN<4+p5Km=j#YB-2oJ2-yB^ri>8S69;Hpzw;UyZ%H z@$==u0u={euV%F9#RV$lR3ZSc7yIPrT^eE(_Tqqoyc>rU9_7dJNFIf7s=#X%8p%QQ zj9orJ4=OwgOym*#$EGs&hIyBbF__5jW9s7s`^|bX=&U4%Pe^j-Q3XlfJp7mZQnvg2 zA)Hq9X%D6k((oZOHo^KqK7=vwMRWavUs5@3JDU`tHEGIF_}?l%oO8+NG8D)?FM|UC z5yWvB6i;EKQCo1F8TJT42m z68%evD>?pIb`H+~P$EvvN%?uD{spdSRnZxDeoTu?;db-+*5kFi hwN~rd#?uG)?~Kk~u5CZsSZzMpn|)E+Zp=1nt$+Q<(=`A9 delta 1067 zcmY*XziSjh6n-bN}xe#MQ2&e~}La;Sl zE97p2t^a{yYa!_^G-BnSAO_<1<}SocG4BWSzW2@d-uv-CV{dP?RjJBHx|BQV4i8*X zT|K4E`m;Uz_{rAJE(Jf{T;JTV`JOXu z*se~s$k!iEyNC*%suXj5wO-|35`63n8bEe5@ z)h{gQAm9*ynFOs6Bq&pzLNye4lT;JizTEzJ_w&&r0Epv|C`TDaCi(wKi_I)$ zr&`;x(H(+B7aT1(YPR>mQ4|<)q&Y*y7{jE+xR|_{5YsGTF%14Nt)eDozQ|Eof~Nr( zbQiFg#{g)~0TloT4&TA^*GDjt_)I&gKaSACw4C?B|tv#Rf6jt{FN zccpTTYJlD;*IB%jYn%nI28B`4=Kxf4;)_;tFabz+{GiHHk2p5FH*3u(l-MqadQnE*91HZpJ_U0gX<{>i_@% diff --git a/n-body/package.json b/n-body/package.json index 1fb86a8..5b87d05 100644 --- a/n-body/package.json +++ b/n-body/package.json @@ -4,10 +4,9 @@ "license": "Apache-2.0", "private": true, "scripts": { - "asbuild:wasm": "asc assembly/index.ts -b build/as_nbody.wasm -t build/as_nbody.wat -O3 --runtime stub --noAssert --importMemory", - "asbuild:js": "asc assembly/index.ts -j build/as_nbody.js -O3 --runtime stub --noAssert && node scripts/postprocess-js", - "asbuild": "npm run asbuild:wasm && npm run asbuild:js", - "tsbuild": "tsc -p assembly -t ES2017 -m commonjs --outDir build", + "asbuild:wasm": "asc assembly/index.ts --target wasm", + "asbuild": "npm run asbuild:wasm", + "tsbuild": "tsc -p assembly -t esnext -m commonjs --outDir build && node scripts/postprocess", "rsbuild": "cd rust && RUSTFLAGS='-C link-arg=-s' cargo +nightly build --release", "build": "npm run asbuild && npm run tsbuild && npm run rsbuild", "start": "npx serve", @@ -15,6 +14,6 @@ }, "devDependencies": { "assemblyscript": "latest", - "typescript": "^3.9.7" + "typescript": "^4.7.4" } } diff --git a/n-body/scripts/postprocess-js.js b/n-body/scripts/postprocess-js.js deleted file mode 100644 index 9801c05..0000000 --- a/n-body/scripts/postprocess-js.js +++ /dev/null @@ -1,8 +0,0 @@ -const fs = require("fs"); -const path = require("path"); - -const filename = path.join(__dirname, "..", "build" , "as_nbody.js"); -var source = fs.readFileSync(filename, { encoding: "utf8" }); -source = source.replace(/^export var ([^ ]+) =/mg, ($0, $1) => "exports." + $1 + " = "); -source = source.replace("import { abort } from 'env';", "function abort() { throw new Error('abort'); }"); -fs.writeFileSync(filename, source); diff --git a/n-body/scripts/postprocess.js b/n-body/scripts/postprocess.js new file mode 100644 index 0000000..6649dd3 --- /dev/null +++ b/n-body/scripts/postprocess.js @@ -0,0 +1,8 @@ +const fs = require("fs"); +const path = require("path"); + +const filename = path.join(__dirname, "..", "build" , "index.js"); +const source = fs.readFileSync(filename, { encoding: "utf8" }); +// remove uncheckeds +const target = source.replace(/unchecked/g, "") +fs.writeFileSync(filename, target); diff --git a/n-body/tests/index.js b/n-body/tests/index.js index 156a598..b282b14 100644 --- a/n-body/tests/index.js +++ b/n-body/tests/index.js @@ -1,40 +1,19 @@ const fs = require("fs"); -// Load WASM version +// Load AssemblyScript version const nbodyAS = require("../assembly/index.js"); -var nbodyRS; -try { - nbodyRS = require("../rust/index.js"); -} catch (e) {} +// Load Rust/wasm version +let nbodyRS; +try { nbodyRS = require("../rust/index.js"); } catch (e) {} // Load JS version -var src = fs.readFileSync(__dirname + "/../build/as_nbody.js", "utf8") - .replace(/const retasmFunc[^$]*$/g, ""); - -const nbodyAS_JS = eval(src + ";asmFunc")({ - Int8Array, - Int16Array, - Int32Array, - Uint8Array, - Uint16Array, - Uint32Array, - Float32Array, - Float64Array, - Math -}, { - abort: () => { throw Error(); } -}, new ArrayBuffer(0x10000)); - -// Load JS version -src = fs.readFileSync(__dirname + "/../build/index.js", "utf8"); +const jsSource = fs.readFileSync(__dirname + "/../build/index.js", "utf8"); const scopeJS = { - require: () => {}, - exports: {}, - unchecked: expr => expr + require: () => {}, + exports: {} }; - const nbodyJS = new Function( - ...Object.keys(scopeJS).concat(src + "\nreturn exports"))(...Object.values(scopeJS) + ...Object.keys(scopeJS).concat(jsSource + "\nreturn exports"))(...Object.values(scopeJS) ); function gcCollect() { @@ -73,9 +52,6 @@ console.log("\nCOLD SERIES:\n"); prologue("AssemblyScript WASM", steps); epilogue(test(nbodyAS, steps)); -prologue("AssemblyScript JS", steps); -epilogue(test(nbodyAS_JS, steps)); - prologue("JS", steps); epilogue(test(nbodyJS, steps)); @@ -90,9 +66,6 @@ sleep(1000); prologue("AssemblyScript WASM", steps); epilogue(test(nbodyAS, steps)); -prologue("AssemblyScript JS", steps); -epilogue(test(nbodyAS_JS, steps)); - prologue("JS", steps); epilogue(test(nbodyJS, steps)); From 0a7f5936dfdf743beb4afc9ab9c6bd6b12ff8e7d Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Thu, 7 Jul 2022 14:27:47 +0300 Subject: [PATCH 2/4] simplify n-body loading --- n-body/tests/index.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/n-body/tests/index.js b/n-body/tests/index.js index b282b14..fdee8da 100644 --- a/n-body/tests/index.js +++ b/n-body/tests/index.js @@ -7,14 +7,7 @@ let nbodyRS; try { nbodyRS = require("../rust/index.js"); } catch (e) {} // Load JS version -const jsSource = fs.readFileSync(__dirname + "/../build/index.js", "utf8"); -const scopeJS = { - require: () => {}, - exports: {} -}; -const nbodyJS = new Function( - ...Object.keys(scopeJS).concat(jsSource + "\nreturn exports"))(...Object.values(scopeJS) -); +const nbodyJS = require("../build/index.js"); function gcCollect() { if (global.gc) { From 9b1c2840ab67d6174b54fba1acb8512cebe50217 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Fri, 8 Jul 2022 14:43:07 +0300 Subject: [PATCH 3/4] better postprocess --- n-body/scripts/postprocess.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/n-body/scripts/postprocess.js b/n-body/scripts/postprocess.js index 6649dd3..8ad9f43 100644 --- a/n-body/scripts/postprocess.js +++ b/n-body/scripts/postprocess.js @@ -3,6 +3,11 @@ const path = require("path"); const filename = path.join(__dirname, "..", "build" , "index.js"); const source = fs.readFileSync(filename, { encoding: "utf8" }); -// remove uncheckeds -const target = source.replace(/unchecked/g, "") -fs.writeFileSync(filename, target); + +function removeUnchecked(str) { + return str + .replace(/unchecked\((.*?)\)/g, (_, _1) => _1) + .replace(/unchecked\((.*?)\)/g, (_, _1) => _1); +} + +fs.writeFileSync(filename, removeUnchecked(source)); From e21ceea175dfaafc2f6158b3dba0321c6da45152 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Fri, 8 Jul 2022 15:03:22 +0300 Subject: [PATCH 4/4] refactoring --- n-body/tests/index.js | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/n-body/tests/index.js b/n-body/tests/index.js index fdee8da..ef8f154 100644 --- a/n-body/tests/index.js +++ b/n-body/tests/index.js @@ -30,39 +30,29 @@ function test(nbody, steps) { return t; } -var steps = process.argv.length > 2 ? parseInt(process.argv[2], 10) : 20000000; - -function prologue(name, steps) { - console.log("Performing " + steps + " steps (" + name + ") ..."); -} - -function epilogue(time) { - console.log("Took " + (time[0] * 1e3 + time[1] / 1e6) + "ms"); +const steps = process.argv.length > 2 + ? parseInt(process.argv[2], 10) + : 20000000; + +function bench(name, fn) { + console.log(`Performing ${steps} steps (${name}) ...`); + const time = test(fn, steps); + console.log(`Took ${(time[0] * 1e3 + time[1] / 1e6).toFixed(0)} ms`); } console.log("\nCOLD SERIES:\n"); -prologue("AssemblyScript WASM", steps); -epilogue(test(nbodyAS, steps)); - -prologue("JS", steps); -epilogue(test(nbodyJS, steps)); - +bench("AssemblyScript WASM", nbodyAS); +bench("JS", nbodyJS); if (nbodyRS) { - prologue("Rust WASM", steps); - epilogue(test(nbodyRS, steps)); + bench("Rust WASM", nbodyRS); } console.log("\nWARMED UP SERIES:\n"); sleep(1000); -prologue("AssemblyScript WASM", steps); -epilogue(test(nbodyAS, steps)); - -prologue("JS", steps); -epilogue(test(nbodyJS, steps)); - +bench("AssemblyScript WASM", nbodyAS); +bench("JS", nbodyJS); if (nbodyRS) { - prologue("Rust WASM", steps); - epilogue(test(nbodyRS, steps)); + bench("Rust WASM", nbodyRS); }