{"id":319468,"date":"2021-03-12T15:00:45","date_gmt":"2021-03-12T15:00:45","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=319468"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=319468","title":{"rendered":"\u0420\u0430\u0437\u0433\u043e\u043d\u044f\u0435\u043c JS-\u043f\u0430\u0440\u0441\u0435\u0440 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e WebAssembly (\u0447\u0430\u0441\u0442\u044c 3: SIMD)"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/post\/545272\/\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u043c\u044b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u043d\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e SWAR-\u0445\u0438\u043d\u0442\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 8 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0446\u0438\u0444\u0440 \u0432 \u043e\u0434\u043d\u043e \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0435 32bit-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041d\u043e \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0443 \u043d\u0430\u0441, \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c, \u043d\u0435\u0432\u0435\u043b\u0438\u043a\u0438 &#8212; \u0434\u043e 3 \u0446\u0438\u0444\u0440? \u0422\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u0432\u043f\u043e\u043b\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e <strong>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c 32bit-\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438<\/strong>, \u0430 SWAR \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u0437\u0430 2 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u043c\u0435\u0441\u0442\u043e 3 &#8212; \u0441\u043f\u043b\u043e\u0448\u043d\u043e\u0439 \u0432\u044b\u0438\u0433\u0440\u044b\u0448!<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0448 \u043a\u043e\u0434 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0432\u044b\u0439 \u0431\u043b\u043e\u043a \u0438\u0437 4 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0441\u044f 32bit-\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438, \u0430 \u0435\u0441\u043b\u0438 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0432\u0442\u043e\u0440\u043e\u0439 \u0431\u043b\u043e\u043a \u0438\u0437 8 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 &#8212; \u0443\u0436\u0435 64bit-\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438.<\/p>\n<p>\u0418&#8230; \u0432\u043c\u0435\u0441\u0442\u043e 26ms \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c <strong>28ms<\/strong>! \u0417\u043d\u0430\u0447\u0438\u0442, \u043d\u0430\u0448\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u0438\u043d\u044b \u0447\u0438\u0441\u0435\u043b \u043d\u0435 \u043e\u043f\u0440\u0430\u0432\u0434\u0430\u043b\u043e\u0441\u044c, \u0438 \u0432 \u043f\u0435\u0440\u0432\u043e\u043c \u0431\u043b\u043e\u043a\u0435 \u0432\u044b\u0433\u043e\u0434\u043d\u0435\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4ba\/a2c\/9e3\/4baa2c9e3962b38a3165fef4f05184bf.jpg\" alt=\"\u0431\u043e\u043b\u044c\u0448\u0438\u0435 - \u043d\u043e \u043f\u043e 5, \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0435 - \u043d\u043e \u043f\u043e 3\" title=\"\u0431\u043e\u043b\u044c\u0448\u0438\u0435 - \u043d\u043e \u043f\u043e 5, \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0435 - \u043d\u043e \u043f\u043e 3\" width=\"600\" height=\"400\"><figcaption>\u0431\u043e\u043b\u044c\u0448\u0438\u0435 &#8212; \u043d\u043e \u043f\u043e 5, \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0435 &#8212; \u043d\u043e \u043f\u043e 3<\/figcaption><\/figure>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430 &#8212; \u043b\u0443\u0447\u0448\u0435? \u0418 \u0442\u0430\u043a\u0438\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b \u0435\u0441\u0442\u044c &#8212; \u044d\u0442\u043e 128-\u0431\u0438\u0442\u043d\u044b\u0435 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/SSE\">SSE-\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b<\/a> <strong>XMM &#8212; \u0432 WebAssembly<\/strong> \u043e\u043d\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043d\u0430\u043c \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441 \u0442\u0438\u043f\u043e\u043c <code>v128<\/code> \u0438 <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md\">\u0441\u0443\u043f\u0435\u0440\u0441\u043a\u0430\u043b\u044f\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \u043d\u0438\u043c\u0438<\/a>.<\/p>\n<blockquote>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u043e\u043a\u0430 <strong>\u043d\u0435 \u0432\u0441\u0435<\/strong> \u044d\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/ImplementationStatus.md\">\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 JavaScript-\u0434\u0432\u0438\u0436\u043a\u0430\u0445<\/a>.<\/p>\n<\/blockquote>\n<p>\u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 <code>v128<\/code>-\u0440\u0435\u0433\u0438\u0441\u0442\u0440 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043b\u0438\u0431\u043e \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u044b\u0439 \u0431\u043b\u043e\u043a (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0431\u0438\u0442\u043e\u0432\u044b\u0445 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 <code>and, or, xor, not<\/code>), \u043b\u0438\u0431\u043e \u043a\u0430\u043a \u043d\u0430\u0431\u043e\u0440 \u0431\u043b\u043e\u043a\u043e\u0432 \u043c\u0435\u043d\u044c\u0448\u0435\u0439 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u0438:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/67c\/90c\/73e\/67c90c73e04cb7ad861416ca29266bc6.png\" width=\"681\" height=\"266\"><figcaption><\/figcaption><\/figure>\n<h2>\u041a\u0430\u043a \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c SIMD \u0432 Node.js<\/h2>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0448 &#171;\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440&#187; <code>compile-test.js<\/code>: \u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"javascript\">const wasmModule = wabt.parseWat(   inputWat , readFileSync(inputWat, 'utf8') , {simd : true} \/\/ \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 SIMD-feature );<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u0440\u0443\u0433\u0438\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 &#171;\u0444\u0438\u0447\u0438&#187; \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 WASM \u043c\u043e\u0436\u043d\u043e \u043d\u0430 <a href=\"https:\/\/webassembly.github.io\/wabt\/demo\/wat2wasm\/\">\u0434\u0435\u043c\u043e-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 wat2wasm<\/a>.<\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 Node.js \u043f\u043e\u043a\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 SIMD \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430\u0448 \u043f\u0430\u0440\u0441\u0435\u0440 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 <a href=\"https:\/\/nodejs.org\/api\/cli.html#cli_v8_options\">V8-\u043e\u043f\u0446\u0438\u044f\u043c\u0438<\/a>:<\/p>\n<pre><code>  --experimental-wasm-simd (enable prototype SIMD opcodes for wasm)         type: bool  default: false   --wasm-simd-post-mvp (allow experimental SIMD operations for prototyping that are not included in the current proposal)         type: bool  default: false<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0430 \u0437\u0430\u043f\u0443\u0441\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"bash\">node --experimental-wasm-simd --wasm-simd-post-mvp --expose-gc buffers-test.js<\/code><\/pre>\n<h2>SIMD-\u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043d\u0430\u0442\u0443\u0440\u0430\u043b\u044c\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u043d\u0430 WASM<\/h2>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u0442\u0435 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0447\u0442\u043e \u0438 \u0434\u043b\u044f SWAR-\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u043d\u043e \u0443\u0436\u0435 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 <code>v128<\/code>-\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439. \u0417\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0432\u043e\u0437\u044c\u043c\u0435\u043c <a href=\"https:\/\/stackoverflow.com\/questions\/35127060\/how-to-implement-atoi-using-simd\">\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u043d\u0430 StackOverflow<\/a>.<\/p>\n<h4>\u0423\u0437\u043d\u0430\u0435\u043c \u0434\u043b\u0438\u043d\u0443 \u0447\u0438\u0441\u043b\u0430<\/h4>\n<ol>\n<li>\n<p>\u0432\u044b\u0447\u0438\u0442\u0430\u0435\u043c &#171;\u043d\u0443\u043b\u0435\u0432\u043e\u0439&#187; \u0441\u0438\u043c\u0432\u043e\u043b <code>0x30<\/code> \u0438\u0437 \u043a\u0430\u0436\u0434\u043e\u0433\u043e, <strong>\u0441 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u0447\u0435\u0440\u0435\u0437 0<\/strong> &#8212; \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0430\u0448\u0438 \u0441\u0442\u043e\u043f-\u0441\u0438\u043c\u0432\u043e\u043b\u044b <code>0x0A, 0x20 \u0438 0x2C<\/code> \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u044f\u0442\u0441\u044f \u0432 <code>0xDA, 0xF0 \u0438 0xFC<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u0430\u0439\u0442\u0430, \u0447\u0442\u043e \u043e\u043d <code>&lt;= 0x09<\/code> &#8212; \u0442\u043e \u0435\u0441\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0441\u044f \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 <code>0x30..0x39<\/code>, \u0447\u0442\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c <code>'0'..'9'<\/code><\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043f\u0435\u0440\u0432\u044b\u0439 <code>false<\/code>-\u0431\u0430\u0439\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>ctz(not(bitmask))<\/code> &#8212; \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0442\u043e\u043f-\u0441\u0438\u043c\u0432\u043e\u043b\u0430<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0432 \u043a\u043e\u0434\u0435 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0434\u0432\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435-&#171;\u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b&#187;: &#171;\u0432\u0441\u0435 \u043d\u0443\u043b\u0438&#187; \u0438 &#171;\u0432\u0441\u0435 \u0434\u0435\u0432\u044f\u0442\u043a\u0438&#187;:<\/p>\n<pre><code class=\"javascript\">  (global $all_zero v128     (v128.const i8x16 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30)   )   (global $all_nine v128     (v128.const i8x16 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09)   )<\/code><\/pre>\n<pre><code class=\"javascript\">  ;; \u0440\u0430\u0437\u0431\u043e\u0440 \u0447\u0438\u0441\u043b\u0430 - SIMD   (func $parseNumber     (local $ch i32)     (local $xword v128)     (local $xn i32)      ;; xword = line[off..+15]     (local.set $xword       (v128.load align=4         (global.get $off)       )     )      ;; xn = num digits     (local.set $xn       (i32.ctz                         ;;        * = 5         (i32.xor                       ;; 0b...  1  0  0  0  0  0           (i8x16.bitmask               ;; 0b...  0  1  1  1  1  1             (i8x16.le_u                ;; 0x... 00 FF FF FF FF FF               (i8x16.sub               ;; 0x... F0 05 04 03 02 01                 (local.get $xword)     ;; 0x... 20 35 34 33 32 31                 (global.get $all_zero) ;; 0x... 30 30 30 30 30 30                )               (global.get $all_nine)   ;; 0x... 09 09 09 09 09 09             )           )           (i32.const 0xFFFFFFFF)       ;; 0b...  1  1  1  1  1  1         )       )     )<\/code><\/pre>\n<h4>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0441\u0442\u043e\u043f-\u0441\u0438\u043c\u0432\u043e\u043b<\/h4>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8b5\/5d7\/abd\/8b55d7abd922a4710f36c081a46db616.jpeg\" width=\"480\" height=\"285\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u0432\u0437\u044f\u0442\u044c <code>xn<\/code>-\u0439 \u0431\u0430\u0439\u0442 \u0438\u0437 v128-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u043b\u044c\u0437\u044f &#8212; \u043d\u0435\u0442 <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md#accessing-lanes\">\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438<\/a>. \u0417\u0430\u0442\u043e \u0435\u0441\u0442\u044c <code>i8x16.extract_lane<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u0437\u044f\u0442\u044c \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0431\u0430\u0439\u0442 (\u043d\u0430\u0441 \u0432\u043f\u043e\u043b\u043d\u0435 \u0443\u0441\u0442\u0440\u043e\u0438\u0442 <code>#0<\/code>).<\/p>\n<p>\u041d\u043e \u0447\u0442\u043e\u0431\u044b \u0432 \u043d\u0443\u043b\u0435\u0432\u043e\u043c \u0431\u0430\u0439\u0442\u0435 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f <code>xn<\/code>-\u0439, \u043d\u0443\u0436\u043d\u043e <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md#swizzling-using-variable-indices\">&#171;\u043f\u0435\u0440\u0435\u043b\u043e\u0436\u0438\u0442\u044c&#187; \u0431\u0430\u0439\u0442\u044b<\/a> \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u043c\u0430\u0441\u043a\u043e\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>swizzle<\/code>.<\/p>\n<p>\u0410 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043c\u0430\u0441\u043a\u0443, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0443\u044e <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md#create-vector-with-identical-lanes\">\u0438\u0437 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/a> <code>xn<\/code>, \u043d\u0430\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f <code>splat<\/code>.<\/p>\n<pre><code class=\"javascript\">    ;; ch = xword[xn]     (local.set $ch           ;; ch = 0x20       (i8x16.extract_lane_u  ;; xmm[0]         0                    ;; \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430         (i8x16.swizzle       ;; 0x... 20 20 20 20 20 20           (local.get $xword) ;; 0x... 20 35 34 33 32 31           (i8x16.splat       ;; 0x... 05 05 05 05 05 05             (local.get $xn)  ;; xn = 5           )         )       )     )<\/code><\/pre>\n<h4>\u041d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0447\u0438\u0441\u043b\u043e<\/h4>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>swizzle<\/code> &#171;\u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0435\u043c&#187; \u0447\u0438\u0441\u043b\u043e, \u0447\u0442\u043e\u0431\u044b \u043c\u043b\u0430\u0434\u0448\u0438\u0439 \u0440\u0430\u0437\u0440\u044f\u0434 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0432 \u043c\u043b\u0430\u0434\u0448\u0435\u043c \u0431\u0430\u0439\u0442\u0435, \u0438 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u0447\u0438\u0441\u0442\u0438\u043c \u043e\u0442 \u043d\u0435-\u0446\u0438\u0444\u0440 <strong>\u0437\u0430 \u0441\u0447\u0435\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u044d\u0442\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 &#171;\u0437\u0430\u043d\u0443\u043b\u044f\u0442\u044c&#187; \u0431\u0430\u0439\u0442\u044b<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0431\u043e\u043b\u044c\u0448\u0435 <code>0x0F<\/code>.<\/p>\n<pre><code class=\"javascript\">  (global $shuf_reverse v128     (v128.const i8x16 0x0F 0x0E 0x0D 0x0C 0x0B 0x0A 0x09 0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01 0x00)   )   (global $all_digit v128     (v128.const i8x16 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F)   )<\/code><\/pre>\n<pre><code class=\"javascript\">    ;; clean &amp; reverse     (local.set $xword       (v128.and                        ;; 0x... 00 01 02 03 04 05         (i8x16.swizzle                 ;; 0x... 00 31 32 33 34 35           (local.get $xword)           ;; 0x... 20 35 34 33 32 31           (i8x16.sub                   ;; 0x... FF 00 01 02 03 04             (global.get $shuf_reverse) ;; 0x... 0A 0B 0C 0D 0E 0F             (i8x16.splat               ;; 0x... 0B 0B 0B 0B 0B 0B               (i32.sub                 ;; = 0x0B                 (i32.const 16)                 (local.get $xn)        ;; xn = 5               )             )           )         )         (global.get $all_digit)        ;; 0x... 0F 0F 0F 0F 0F 0F       )     )<\/code><\/pre>\n<h4>SIMD-\u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f<\/h4>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 (\u0447\u0438\u0442\u0430\u0439, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430), \u043a\u043e\u0433\u0434\u0430 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0437 16 \u0431\u0430\u0439\u0442\u043e\u0432 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f <strong>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0446\u0438\u0444\u0440<\/strong>, \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0435\u0441\u044f\u0442\u0438\u0447\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u044f\u0434\u0430\u043c \u0447\u0438\u0441\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c &#8212; \u0432 \u043c\u043b\u0430\u0434\u0448\u0435\u043c \u0431\u0430\u0439\u0442\u0435 \u043c\u043b\u0430\u0434\u0448\u0438\u0439 \u0440\u0430\u0437\u0440\u044f\u0434:<\/p>\n<pre><code>P O N M L K J I H G F E D C B A == A * 10^0 + B * 10^1 + C * 10^2 + D * 10^3 + ...<\/code><\/pre>\n<p>\u0412 \u0438\u0434\u0435\u0430\u043b\u0435, \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043d\u0430\u043c \u043f\u043e\u0434\u043e\u0448\u043b\u0438 \u0431\u044b <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md#extended-integer-multiplication\">\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f<\/a> \u0442\u0438\u043f\u0430 <code>i16x8.extmul_[low|high]_i8x16_u<\/code> \u0438 <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md#extended-pairwise-integer-addition\">\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043f\u0430\u0440\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/a> <code>i16x8.extadd_pairwise_i8x16_u<\/code>.<\/p>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0438\u0437 \u044d\u0442\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0443\u043c\u043d\u043e\u0436\u0430\u0435\u0442 \u043d\u0438\u0436\u043d\u0438\u0435\/\u0432\u0435\u0440\u0445\u043d\u0438\u0435 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u044b \u043f\u0430\u0440\u044b XMM-\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432, \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044f \u0438\u0445 \u043a\u0430\u043a \u043d\u0430\u0431\u043e\u0440 8bit-\u0447\u0438\u0441\u0435\u043b \u043d\u0430 \u0432\u0445\u043e\u0434\u0435, \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u044f \u0432\u044b\u0445\u043e\u0434 \u0434\u043e 16bit-\u0447\u0438\u0441\u0435\u043b:<\/p>\n<pre><code>0x...   FC   FD   FE   FF          x    x    x    x 0x...   04   03   02   01          =    =    =    = 0x... 03F0 02F7 01FC 00FF = i16x8.extmul_low_i8x16_u<\/code><\/pre>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043f\u0430\u0440\u043d\u043e \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 &#171;\u0447\u0438\u0441\u043b\u0430&#187; \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435:<\/p>\n<pre><code>0x... FC + FD   FE + FF 0x...    01F9      01FD = i16x8.extadd_pairwise_i8x16_u<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/ImplementationStatus.md\">\u043e\u043d\u0438 \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f<\/a>, \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0438\u0445 \u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0432\u044b\u0434\u0435\u043b\u0438\u043c \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>i16x8.widen_low_i8x16_u<\/code>  \u043d\u0438\u0436\u043d\u044e\u044e \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0443, \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0432 8bit-\u0447\u0438\u0441\u043b\u0430 \u0434\u043e 16bit \u0438 \u043f\u0435\u0440\u0435\u043c\u043d\u043e\u0436\u0438\u043c \u0441 \u043c\u0430\u0441\u043a\u043e\u0439 \u0441\u0442\u0435\u043f\u0435\u043d\u0435\u0439 10:<\/p>\n<pre><code class=\"javascript\">  (global $stepA_pow10 v128     (v128.const i16x8 1 10 100 1000 1 10 100 1000)   ) ;; ...     ;; i16x8.extmul_low_i8x16_u - not implemented     (local.set $xtempL       (i16x8.mul                  ;; H000 G00  F0   E  D000 C00  B0   A         (i16x8.widen_low_i8x16_u  ;;  0 H|0 G|0 F|0 E | 0 D|0 C|0 B|0 A           (local.get $xword)      ;;                ... H G F E D C B A         )         (global.get $stepA_pow10) ;; 1000 100  10   1  1000 100  10   1       )     )<\/code><\/pre>\n<p>\u0421\u0442\u0435\u043f\u0435\u043d\u0438 \u0432\u044b\u0431\u0440\u0430\u043d\u044b \u0441 \u0442\u0430\u043a\u0438\u043c \u0443\u043c\u044b\u0441\u043b\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0438 \u0432 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 16bit-\u044f\u0447\u0435\u0435\u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0435 \u043c\u043e\u0433 \u043f\u0440\u0435\u0432\u0437\u043e\u0439\u0442\u0438 2^16.<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u044d\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u043c <code>extadd_pairwise<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0438\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0434\u0432\u0438\u0433\u0430, \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438, \u043a\u043e\u0433\u0434\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0438\u0442\u043e\u0432\u043e\u0439 \u043c\u0430\u0441\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">    ;; i32x4.extadd_pairwise_i16x8_u - not implemented     (local.set $xtempL       (i16x8.add                  ;; H000 HG00   F0   FE D000 DC00   B0   BA         (i32x4.shr_u              ;;    0 H000    0   F0    0 D000    0   B0           (local.get $xtempL)     ;; H000  G00   F0    E D000  C00   B0    A           (i32.const 16)         )         (local.get $xtempL)       ;; H000  G00   F0    E D000  C00   B0    A       )     )<\/code><\/pre>\n<p>\u0422\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u043e \u0441\u0442\u0430\u0440\u0448\u0438\u043c\u0438 \u0431\u0430\u0439\u0442\u0430\u043c\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430:<\/p>\n<pre><code class=\"javascript\">    (local.set $xtempH       (i16x8.mul                  ;; P000 O00  N0   M  L000 K00  J0   I         (i16x8.widen_high_i8x16_u ;;  0 P|0 O|0 N|0 M | 0 L|0 K|0 J|0 I           (local.get $xword)      ;;  P O N M L K J I ...         )                                                                       (global.get $stepA_pow10) ;; 1000 100  10   1  1000 100  10   1       )                                )      (local.set $xtempH       (i16x8.add                  ;; P000 PO00   N0   NM L000 LK00   J0   JI         (i32x4.shr_u              ;;    0 P000    0   N0    0 L000    0   J0           (local.get $xtempH)     ;; P000  O00   N0    M L000  K00   J0    I           (i32.const 16)         )         (local.get $xtempH)       ;; P000  O00   N0    M L000  K00   J0    I       )     )<\/code><\/pre>\n<p>\u0423\u043f\u0430\u043a\u0443\u0435\u043c \u043e\u0431\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u043e\u0434\u0438\u043d \u0440\u0435\u0433\u0438\u0441\u0442\u0440, \u043e\u0442\u0431\u0440\u043e\u0441\u0438\u0432 \u043b\u0438\u0448\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>shuffle<\/code>:<\/p>\n<pre><code class=\"javascript\">    ;; shuffle     (local.set $xword       (i8x16.shuffle              ;; PO00   NM LK00   JI HG00   FE DC00   BA         0x00 0x01 0x04 0x05 0x08 0x09 0x0C 0x0D 0x10 0x11 0x14 0x15 0x18 0x19 0x1C 0x1D          (local.get $xtempL)       ;; H000 HG00   F0   FE D000 DC00   B0   BA         (local.get $xtempH)       ;; P000 PO00   N0   NM L000 LK00   J0   JI       )     )<\/code><\/pre>\n<p>\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u043c \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435-\u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0445 \u0431\u043b\u043e\u043a\u043e\u0432 \u0435\u0449\u0435 \u0434\u0432\u0430\u0436\u0434\u044b &#8212; \u0434\u043b\u044f i16x8 \u0438 i32x4, \u0443\u0436\u0435 \u0441 \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043c\u0430\u0441\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">  (global $stepB_pow10 v128     (v128.const i32x4 1 10000 100000000 0)   )   (global $stepB_mask v128     (v128.const i32x4 0xFFFFFFFF 0x00000000 0xFFFFFFFF 0x00000000)   ) ;; ...     (local.set $xword       (i16x8.add                  ;; PO00 PONM LK00 LKJI HG00 HGFE DC00 DCBA         (i32x4.shr_u              ;;    0 PO00    0 LK00    0 HG00    0 DC00           (local.get $xword)      ;; PO00   NM LK00   JI HG00   FE DC00   BA           (i32.const 16)         )         (local.get $xword)        ;; PO00   NM LK00   JI HG00   FE DC00   BA       )     )      (local.set $xword       (v128.and                   ;;    0 PONM    0 LKJI    0 HGFE    0 DCBA         (local.get $xword)        ;; PO00 PONM LK00 LKJI HG00 HGFE DC00 DCBA         (global.get $stepA_mask)  ;; 0000 FFFF 0000 FFFF 0000 FFFF 0000 FFFF 0x...       )     )      (local.set $xword       (i32x4.mul                  ;;         0 LKJI00000000  HGFE0000     DCBA         (local.get $xword)        ;;    0 PONM       0 LKJI    0 HGFE   0 DCBA         (global.get $stepB_pow10) ;;         0    100000000     10000        1       )                                )      (local.set $xword       (i32x4.add                  ;;         0 LKJI00000000  HGFE0000 HGFEDCBA         (i64x2.shr_u              ;;         0            0         0 HGFE0000           (local.get $xword)      ;;         0 LKJI00000000  HGFE0000     DCBA           (i32.const 32)         )         (local.get $xword)        ;;         0 LKJI00000000  HGFE0000     DCBA       )     )      (local.set $xword       (v128.and                   ;;         0 LKJI00000000         0 HGFEDCBA         (local.get $xword)        ;;         0 LKJI00000000  HGFE0000 HGFEDCBA         (global.get $stepB_mask)  ;;  00000000     FFFFFFFF  00000000 FFFFFFFF 0x...       )     )<\/code><\/pre>\n<p>\u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u0441\u0430\u043c\u044b\u0439 \u0441\u0442\u0430\u0440\u0448\u0438\u0439 \u0431\u043b\u043e\u043a \u0446\u0438\u0444\u0440 <code>'PONM'<\/code> \u043c\u044b \u043f\u043e\u0442\u0435\u0440\u044f\u043b\u0438 \u043f\u0440\u0438 \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043d\u0435 \u0432\u043b\u0435\u0437 \u0432 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c i32. \u0415\u0441\u043b\u0438 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u044e\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0439 \u0434\u043b\u0438\u043d\u044b, \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0442\u0430\u0449\u0438\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0447\u0435\u0440\u0435\u0437 <code>extract_lane<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 SIMD-\u0432\u0435\u0440\u0441\u0438\u0438<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">(module   (import \"js\" \"memory\" (memory 1))    ;; \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \"\u043a\u0443\u0440\u0441\u043e\u0440\u0430\"   (global $off (import \"js\" \"off\") (mut i32))   ;; \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435   (global $val (mut i64)     (i64.const 0)   )   (global $mask (mut i32)     (i32.const 0)   )   (global $state (mut i32)     (i32.const 0)   )   (global $key (mut i32)     (i32.const 0)   )    (global $stepA_pow10 v128     (v128.const i16x8 1 10 100 1000 1 10 100 1000)   )   (global $stepB_pow10 v128     (v128.const i32x4 1 10000 100000000 0)   )    (global $stepA_mask v128     (v128.const i16x8 0xFFFF 0x0000 0xFFFF 0x0000 0xFFFF 0x0000 0xFFFF 0x0000)   )   (global $stepB_mask v128     (v128.const i32x4 0xFFFFFFFF 0x00000000 0xFFFFFFFF 0x00000000)   )   (global $all_zero v128     (v128.const i8x16 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30)   )   (global $all_nine v128     (v128.const i8x16 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09)   )   (global $shuf_reverse v128     (v128.const i8x16 0x0F 0x0E 0x0D 0x0C 0x0B 0x0A 0x09 0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01 0x00)   )   (global $all_digit v128     (v128.const i8x16 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F)   )    ;; \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043a\u043e\u0441\u0432\u0435\u043d\u043d\u043e\u0439 \u0430\u0434\u0440\u0435\u0441\u0430\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439   (table 128 anyfunc)   (elem (i32.const 0)     $null ;; 00     $null ;;  1     $null ;;  2     $null ;;  3     $null ;;  4     $null ;;  5     $null ;;  6     $null ;;  7     $null ;;  8     $null ;;  9     $null ;;  A     $null ;;  B     $null ;;  C     $null ;;  D     $null ;;  E     $null ;;  F     $null ;; 10     $null ;;  1     $null ;;  2     $null ;;  3     $null ;;  4     $null ;;  5     $null ;;  6     $null ;;  7     $null ;;  8     $null ;;  9     $null ;;  A     $null ;;  B     $null ;;  C     $null ;;  D     $null ;;  E     $null ;;  F     $null ;; 20     $null ;;  1     $null ;;  2     $null ;;  3     $null ;;  4     $null ;;  5     $null ;;  6     $null ;;  7     $null ;;  8     $null ;;  9     $null ;;  A     $null ;;  B     $null ;;  C     $null ;;  D     $null ;;  E     $null ;;  F     $null ;; 30     $null ;;  1     $null ;;  2     $null ;;  3     $null ;;  4     $null ;;  5     $null ;;  6     $null ;;  7     $null ;;  8     $null ;;  9     $null ;;  A     $null ;;  B     $null ;;  C     $null ;;  D     $null ;;  E     $null ;;  F     $null ;; 40     $null ;;  1     $null ;;  2     $null ;;  3     $null ;;  4     $null ;;  5     $null ;;  6     $null ;;  7     $null ;;  8     $null ;;  9     $null ;;  A     $null ;;  B     $null ;;  C     $null ;;  D     $null ;;  E     $null ;;  F     $null ;; 50     $null ;;  1     $null ;;  2     $null ;;  3     $null ;;  4     $null ;;  5     $null ;;  6     $null ;;  7     $null ;;  8     $null ;;  9     $null ;;  A     $null ;;  B     $null ;;  C     $null ;;  D     $null ;;  E     $null ;;  F     $null ;; 60     $null ;;  1     $null ;;  2     $null ;;  3     $step_d ;;  4     $null ;;  5     $null ;;  6     $null ;;  7     $step_h ;;  8     $null ;;  9     $null ;;  A     $null ;;  B     $step_l ;;  C     $null ;;  D     $null ;;  E     $null ;;  F     $null ;; 70     $null ;;  1     $step_r ;;  2     $step_s ;;  3     $step_t ;;  4     $null ;;  5     $null ;;  6     $step_w ;;  7     $null ;;  8     $null ;;  9     $null ;;  A     $null ;;  B     $null ;;  C     $null ;;  D     $null ;;  E     $null ;;  F   )    ;; \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043c\u0430\u0441\u043a\u0443 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435   (func $setData     ;; buf[key &lt;&lt; 3] = val     (i64.store       (i32.shl         (global.get $key)         (i32.const 3)       )       (global.get $val)     )     ;; mask |= 1 &lt;&lt; key     (global.set $mask       (i32.or         (global.get $mask)         (i32.shl           (i32.const 1)           (global.get $key)         )       )     )   )    (func $step (param $off_v i32)     ;; $off += $off_v     (global.set $off       (i32.add         (global.get $off)         (local.get $off_v)       )     )   )    ;; \u0440\u0430\u0437\u0431\u043e\u0440 \u0447\u0438\u0441\u043b\u0430 - SIMD   (func $parseNumber     (local $ch i32)     (local $xword v128)     (local $xn i32)     (local $xtempL v128)     (local $xtempH v128)      ;; xword = line[off..+15]     (local.set $xword       (v128.load align=4         (global.get $off)       )     )      ;; xn = num digits     (local.set $xn       (i32.ctz         (i32.xor           (i8x16.bitmask             (i8x16.le_u               (i8x16.sub                 (local.get $xword)                 (global.get $all_zero)               )               (global.get $all_nine)             )           )           (i32.const 0xFFFFFFFF)         )       )     )      ;; ch = xword[xn]     (local.set $ch           ;; ch = 0x20       (i8x16.extract_lane_u  ;; xmm[0]         0                    ;; \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430         (i8x16.swizzle       ;; 0x... 20 20 20 20 20 20           (local.get $xword) ;; 0x... 20 35 34 33 32 31           (i8x16.splat       ;; 0x... 05 05 05 05 05 05             (local.get $xn)  ;; xn = 5           )         )       )     )      ;; clean &amp; reverse     (local.set $xword       (v128.and                        ;; 0x... 00 01 02 03 04 05         (i8x16.swizzle                 ;; 0x... 00 31 32 33 34 35           (local.get $xword)           ;; 0x... 20 35 34 33 32 31           (i8x16.sub                   ;; 0x... FF 00 01 02 03 04             (global.get $shuf_reverse) ;; 0x... 0A 0B 0C 0D 0E 0F             (i8x16.splat               ;; 0x... 0B 0B 0B 0B 0B 0B               (i32.sub                 ;; = 0x0B                 (i32.const 16)                 (local.get $xn)        ;; xn = 5               )             )           )         )         (global.get $all_digit)        ;; 0x... 0F 0F 0F 0F 0F 0F       )     )      ;; i16x8.extmul_low_i8x16_u - not implemented     (local.set $xtempL       (i16x8.mul                  ;; H000 G00  F0   E  D000 C00  B0   A         (i16x8.widen_low_i8x16_u  ;;  0 H|0 G|0 F|0 E | 0 D|0 C|0 B|0 A           (local.get $xword)      ;;                ... H G F E D C B A         )         (global.get $stepA_pow10) ;; 1000 100  10   1  1000 100  10   1       )     )      ;; i32x4.extadd_pairwise_i16x8_u - not implemented     (local.set $xtempL       (i16x8.add                  ;; H000 HG00   F0   FE D000 DC00   B0   BA         (i32x4.shr_u              ;;    0 H000    0   F0    0 D000    0   B0           (local.get $xtempL)     ;; H000  G00   F0    E D000  C00   B0    A           (i32.const 16)         )         (local.get $xtempL)       ;; H000  G00   F0    E D000  C00   B0    A       )     )          (local.set $xtempH       (i16x8.mul                  ;; P000 O00  N0   M  L000 K00  J0   I         (i16x8.widen_high_i8x16_u ;;  0 P|0 O|0 N|0 M | 0 L|0 K|0 J|0 I           (local.get $xword)      ;;  P O N M L K J I ...         )                                                                       (global.get $stepA_pow10) ;; 1000 100  10   1  1000 100  10   1       )                                )      (local.set $xtempH       (i16x8.add                  ;; P000 PO00   N0   NM L000 LK00   J0   JI         (i32x4.shr_u              ;;    0 P000    0   N0    0 L000    0   J0           (local.get $xtempH)     ;; P000  O00   N0    M L000  K00   J0    I           (i32.const 16)         )         (local.get $xtempH)       ;; P000  O00   N0    M L000  K00   J0    I       )     )      ;; shuffle     (local.set $xword       (i8x16.shuffle              ;; PO00   NM LK00   JI HG00   FE DC00   BA         0x00 0x01 0x04 0x05 0x08 0x09 0x0C 0x0D 0x10 0x11 0x14 0x15 0x18 0x19 0x1C 0x1D          (local.get $xtempL)       ;; H000 HG00   F0   FE D000 DC00   B0   BA         (local.get $xtempH)       ;; P000 PO00   N0   NM L000 LK00   J0   JI       )     )      (local.set $xword       (i16x8.add                  ;; PO00 PONM LK00 LKJI HG00 HGFE DC00 DCBA         (i32x4.shr_u              ;;    0 PO00    0 LK00    0 HG00    0 DC00           (local.get $xword)      ;; PO00   NM LK00   JI HG00   FE DC00   BA           (i32.const 16)         )         (local.get $xword)        ;; PO00   NM LK00   JI HG00   FE DC00   BA       )     )      (local.set $xword       (v128.and                   ;;    0 PONM    0 LKJI    0 HGFE    0 DCBA         (local.get $xword)        ;; PO00 PONM LK00 LKJI HG00 HGFE DC00 DCBA         (global.get $stepA_mask)  ;; 0000 FFFF 0000 FFFF 0000 FFFF 0000 FFFF 0x...       )     )      (local.set $xword       (i32x4.mul                  ;;         0 LKJI00000000  HGFE0000     DCBA         (local.get $xword)        ;;    0 PONM       0 LKJI    0 HGFE   0 DCBA         (global.get $stepB_pow10) ;;         0    100000000     10000        1       )                                )      (local.set $xword       (i32x4.add                  ;;         0 LKJI00000000  HGFE0000 HGFEDCBA         (i64x2.shr_u              ;;         0            0         0 HGFE0000           (local.get $xword)      ;;         0 LKJI00000000  HGFE0000     DCBA           (i32.const 32)         )         (local.get $xword)        ;;         0 LKJI00000000  HGFE0000     DCBA       )     )      (local.set $xword       (v128.and                   ;;         0 LKJI00000000         0 HGFEDCBA         (local.get $xword)        ;;         0 LKJI00000000  HGFE0000 HGFEDCBA         (global.get $stepB_mask)  ;;  00000000     FFFFFFFF  00000000 FFFFFFFF 0x...       )     )      ;; return     (global.set $val       (i64.add         (i64x2.extract_lane           0           (local.get $xword)         )         (i64x2.extract_lane           1           (local.get $xword)         )       )     )      ;; \u0448\u0430\u0433\u0430\u0435\u043c \u043d\u0430 n \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432     ;; ch == '\\n' || ch == ' ' =&gt; +1     ;; ch == ','               =&gt; +2     (call $step       (i32.add         (local.get $xn)         (i32.add           (i32.const 1)           (i32.eq             (local.get $ch)             (i32.const 0x2C)           )         )       )     )   )    ;; [state, off] = [state_v, off + off_v]   (func $iterate0 (param $state_v i32) (param $off_v i32)     ;; state = state_v     (global.set $state       (local.get $state_v)     )     ;; off += off_v     (call $step       (local.get $off_v)     )   )    ;; [key, off] = [state + state_v, off + off_v]   (func $iterate1 (param $state_v i32) (param $off_v i32)     ;; key = state + state_v     (global.set $key       (i32.add         (global.get $state)         (local.get $state_v)       )     )     ;; off += off_v     (call $step       (local.get $off_v)     )   )    (func $null (result i32)     i32.const 0   )    (func $step_s (result i32) ;; shared     ;; $state = 0     ;; $off += 7     (call $iterate0       (i32.const 0)       (i32.const 7)     )      i32.const 1   )    (func $step_l (result i32) ;; local     ;; $state = 4     ;; $off += 6     (call $iterate0       (i32.const 4)       (i32.const 6)     )      i32.const 1   )    (func $step_t (result i32) ;; temp     ;; $state = 8     ;; $off += 5     (call $iterate0       (i32.const 8)       (i32.const 5)     )      i32.const 1   )    (func $step_h (result i32) ;; hit     ;; key = state + 0;     ;; $off += 4     (call $iterate1       (i32.const 0)       (i32.const 4)     )     ;;     call $parseNumber     call $setData      i32.const 1   )    (func $step_r (result i32) ;; read     ;; key = state + 1;     ;; $off += 5     (call $iterate1       (i32.const 1)       (i32.const 5)     )     ;;     call $parseNumber     call $setData      i32.const 1   )    (func $step_d (result i32) ;; dirtied     ;; key = state + 2;     ;; $off += 8     (call $iterate1       (i32.const 2)       (i32.const 8)     )     ;;     call $parseNumber     call $setData      i32.const 1   )    (func $step_w (result i32) ;; written     ;; key = state + 3;     ;; $off += 8     (call $iterate1       (i32.const 3)       (i32.const 8)     )     ;;     call $parseNumber     call $setData      i32.const 1   )    (func (export \"parseBuffers\") (result i32)     ;; mask = 0     (global.set $mask       (i32.const 0)     )     ;; off += 'Buffers: '.length     (global.set $off       (i32.add         (global.get $off)         (i32.const 9)       )     )     ;; for (...)     (block       (loop         ;; if (table[line[off]]()) continue;         (br_if 0           (call_indirect (result i32)             (i32.load8_u               (global.get $off)             )           )         )         ;; break, end loop       )     )      ;; \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435     (i32.store       (i32.const 0xFFFC) ;; 16383 * 4       (global.get $off)     )     ;; \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043c\u0430\u0441\u043a\u0443     global.get $mask   ) )<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c! \u0423\u0432\u044b, \u043d\u0430\u0448\u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043d\u0435 \u043e\u043f\u0440\u0430\u0432\u0434\u0430\u043b\u0438\u0441\u044c &#8212; <strong>\u0432\u0440\u0435\u043c\u044f \u0443\u0445\u0443\u0434\u0448\u0438\u043b\u043e\u0441\u044c \u0441 26ms \u0434\u043e 30ms<\/strong>. \u041d\u0435\u0443\u0436\u0435\u043b\u0438 \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0442\u0430\u043a\u0443\u044e \u043f\u043b\u043e\u0445\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0447\u0438\u0441\u0435\u043b?<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u044b\u043a\u043b\u044e\u0447\u0438\u043c \u0432\u0441\u0435 \u044d\u0442\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f, \u043e\u0441\u0442\u0430\u0432\u0438\u0432 \u043b\u0438\u0448\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0446\u0438\u0444\u0440 <code>xn<\/code> \u0438 \u0441\u0442\u043e\u043f-\u0441\u0438\u043c\u0432\u043e\u043b\u0430 <code>ch<\/code> &#8212; \u0438 \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e <strong>\u0443\u0436\u0435 27ms<\/strong>!<\/p>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u043e\u0442\u0435\u0440\u0438 \u0443 \u043d\u0430\u0441 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u0443\u0436\u0435 \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0438 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0431\u043b\u043e\u043a\u043e\u0432, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u044d\u0442\u043e \u0432\u043e\u0432\u0441\u0435 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435 &#8212; \u043c\u044b \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b\u0438 16 \u0431\u0430\u0439\u0442, \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b\u0438 \u0442\u0430\u043c \u043f\u0443\u0441\u0442\u044c \u0434\u0430\u0436\u0435 7 \u0446\u0438\u0444\u0440 \u043f\u043b\u044e\u0441 \u0441\u0442\u043e\u043f-\u0441\u0438\u043c\u0432\u043e\u043b, \u043d\u043e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435-\u0442\u043e 8 \u0431\u0430\u0439\u0442 \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u0432\u044b\u043a\u0438\u043d\u0443\u043b\u0438 \u0438 \u043f\u0435\u0440\u0435\u0447\u0438\u0442\u0430\u0435\u043c \u0438\u0445 \u0437\u0430\u043d\u043e\u0432\u043e.<\/p>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e <strong>SIMD &#8212; \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u043d\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430!<\/strong><\/p>\n<hr>\n<h2>\u0417\u0430\u043c\u0435\u0442\u043a\u0438 \u043d\u0430 \u043f\u043e\u043b\u044f\u0445<\/h2>\n<p>\u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u0432\u044b\u0448\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c? \u041a\u043e\u043d\u0435\u0447\u043d\u043e!<\/p>\n<ol>\n<li>\n<p>\u0427\u0438\u0441\u043b\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0432 <code>v128<\/code>, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0435 \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435, \u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>i8x16.add_sat_u<\/code> \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0447\u043b\u0435\u043d\u0438\u0442\u044c \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b (<code>s, l, t, h, r, d, w<\/code>) \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u044f\u043c\u043e \u0432 <code>xword<\/code>, \u0435\u0441\u043b\u0438 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u0438\u0442\u043e\u0432\u0443\u044e \u043c\u0430\u0441\u043a\u0443 &#171;\u043f\u043e\u0441\u043b\u0435\u043f\u0440\u043e\u0431\u0435\u043b\u044c\u043d\u044b\u0445&#187; \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0430 \u0437\u0430\u0442\u0435\u043c \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0435 \u0432 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0443\u0436\u043d\u044b\u0445 <code>i8<\/code>-\u0431\u043b\u043e\u043a\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0439 &#171;\u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u0441\u0438\u043c\u0432\u043e\u043b&#187; =&gt; <code>{\u0442\u0438\u043f, \u0434\u043b\u0438\u043d\u0430, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435}<\/code>.<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 buffers-test.js<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">const { readFileSync } = require('fs');  const fn = 'buffers-test';  const run = async () =&gt; {   const buffer = readFileSync(`${fn}.wasm`);   const module = await WebAssembly.compile(buffer);      const memory = new WebAssembly.Memory({initial : 1});      const data = readFileSync('buffers.txt');   memory.grow((data.byteLength &gt;&gt; 16) + 8);   const prj32 = new Uint32Array(memory.buffer);   const prj8 = new Uint8Array(memory.buffer);    \/\/ \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u0437 \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e   const off = new WebAssembly.Global({value : 'i32', mutable : true}, 0x80000);    data.copy(prj8, off.value);   \/\/ \u0434\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 '\\n' \u0443 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0438   prj8[off.value + data.length] = 0x0A;    const importObject = {     js : {       memory     , off     }   };    \/\/ 10^N \u0434\u043b\u044f \u0434\u043e\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430   let pow10 = 1;   for (let i = 0; i &lt; 8; i++) {     prj32[(i &lt;&lt; 1) + 32] = pow10;     pow10 *= 10;   }    \/\/ \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0439 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432   let keys = {     's' : 0x010700 \/\/ 'shared '   , 'l' : 0x010604 \/\/ 'local '   , 't' : 0x010508 \/\/ 'temp '   , 'h' : 0x000400 \/\/ 'hit='   , 'r' : 0x000501 \/\/ 'read='   , 'd' : 0x000802 \/\/ 'dirtied='   , 'w' : 0x000803 \/\/ 'written='   };   Object.entries(keys).forEach(([key, val]) =&gt; prj32[48 + key.charCodeAt()] = val);    \/\/ https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Math\/clz32   const clz = Math.clz32;   const ctz = integer =&gt; {     integer |= integer &lt;&lt; 16;     integer |= integer &lt;&lt; 8;     integer |= integer &lt;&lt; 4;     integer |= integer &lt;&lt; 2;     integer |= integer &lt;&lt; 1;     return 32 - clz(~integer) | 0;   };    \/\/ https:\/\/stackoverflow.com\/questions\/43122082\/efficiently-count-the-number-of-bits-in-an-integer-in-javascript\/43122214   const popcnt = n =&gt; {     n = n - ((n &gt;&gt; 1) &amp; 0x55555555)     n = (n &amp; 0x33333333) + ((n &gt;&gt; 2) &amp; 0x33333333)     return ((n + (n &gt;&gt; 4) &amp; 0xF0F0F0F) * 0x1010101) &gt;&gt; 24   };    \/\/ \u043e\u0431\u0440\u0430\u0442\u043d\u0430\u044f \u0431\u0438\u0442\u043e\u0432\u0430\u044f \u043c\u0430\u0441\u043a\u0430   for (let i = 0; i &lt; (1 &lt;&lt; 16); i++) {     if (popcnt(i) &lt; 5) {       let r = 0xFFFFFFFF;       for (let v = i; v; ) {         let bp = 31 - clz(v);         r &lt;&lt;= 8;         r |= bp;         v ^= 1 &lt;&lt; bp;       }       prj32[16384 + i] = r;     }   }    const instance = await WebAssembly.instantiate(module, importObject);   const parseBuffersWASM = instance.exports.parseBuffers;    const buffersKeys = ['shared-hit', 'shared-read', 'shared-dirtied', 'shared-written', 'local-hit', 'local-read', 'local-dirtied', 'local-written', 'temp-hit', 'temp-read', 'temp-dirtied', 'temp-written'];   const m32to64 = 0x100000000;    const parseBuffers = () =&gt; {     let mask = parseBuffersWASM();     switch (mask) {       case 1:         return {'shared-hit'  : prj32[0] + prj32[1] * m32to64};       case 2:         return {'shared-read' : prj32[2] + prj32[3] * m32to64};       case 3:         return {           'shared-hit'  : prj32[0] + prj32[1] * m32to64         , 'shared-read' : prj32[2] + prj32[3] * m32to64         };       default:         let rv = {};         for (let i = 0; mask; mask &gt;&gt;= 1, i++) {           if (mask &amp; 1) {             let off = i &lt;&lt; 1;             rv[buffersKeys[i]] = prj32[off] + prj32[off + 1] * m32to64;           }         }         return rv;     }   };    for (let lim = data.length + off.value; prj32[16383] &lt; lim; ) {     let obj = parseBuffers();   }   off.value = 0x80000;   prj32[16383] = off.value;    const hrb = process.hrtime();   \/\/ -- 8&lt; --   for (let lim = data.length + off.value; prj32[16383] &lt; lim; ) {     let obj = parseBuffers();   }   \/\/ -- 8&lt; --   const hre = process.hrtime(hrb);   const usec = hre[0] * 1e+9 + hre[1];   console.log(usec); };  run();<\/code><\/pre>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 buffers-test.wat<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">(module   (import \"js\" \"func\" (func $js_func (param i32)))   (import \"js\" \"memory\" (memory 1))    ;; \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \"\u043a\u0443\u0440\u0441\u043e\u0440\u0430\"   (global $off (import \"js\" \"off\") (mut i32))   ;; \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435   (global $val (mut i64)     (i64.const 0)   )    (global $stepA_pow10 v128     (v128.const i16x8 1 10 100 1000 1 10 100 1000)   )   (global $stepB_pow10 v128     (v128.const i32x4 1 10000 100000000 0)   )    (global $stepA_mask v128     (v128.const i16x8 0xFFFF 0x0000 0xFFFF 0x0000 0xFFFF 0x0000 0xFFFF 0x0000)   )   (global $stepB_mask v128     (v128.const i32x4 0xFFFFFFFF 0x00000000 0xFFFFFFFF 0x00000000)   )   (global $all_zero v128     (v128.const i8x16 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30)   )   (global $all_nine v128     (v128.const i8x16 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09)   )   (global $shuf_straight v128     (v128.const i8x16 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F)   )   (global $shuf_reverse v128     (v128.const i8x16 0x0F 0x0E 0x0D 0x0C 0x0B 0x0A 0x09 0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01 0x00)   )   (global $all_digit v128     (v128.const i8x16 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F)   )   (global $all_space v128     (v128.const i8x16 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20)   )   (global $all_0A v128     (v128.const i8x16 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A)   )    ;; \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043c\u0430\u0441\u043a\u0443 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438   (func $setData (param $key i32) (param $mask i32) (result i32)     ;; buf[key &lt;&lt; 3] = val     (i64.store       (i32.shl         (local.get $key)         (i32.const 3)       )       (global.get $val)     )     ;; mask |= 1 &lt;&lt; key     (i32.or       (local.get $mask)       (i32.shl         (i32.const 1)         (local.get $key)       )     )   )    ;; \u0440\u0430\u0437\u0431\u043e\u0440 \u0447\u0438\u0441\u043b\u0430 - SIMD   (func $parseNumber (param $xword v128) (param $off i32) (result i32)     (local $xn i32)     (local $xtempL v128)     (local $xtempH v128)      ;; xn = num digits     (local.set $xn       (i32.ctz                           ;;           ^ = 5         (i32.xor                         ;; 0b...     1  0  0  0  0  0           (i32.shr_u                     ;; 0b...     0  1  1  1  1  1             (i8x16.bitmask               ;; 0b...  0  1  1  1  1  1  0               (i8x16.le_u                ;; 0x... 00 FF FF FF FF FF 00                 (i8x16.sub               ;; 0x... F0 05 04 03 02 01 0D                   (local.get $xword)     ;; 0x... 20 35 34 33 32 31 3D                   (global.get $all_zero) ;; 0x... 30 30 30 30 30 30 30                 )                 (global.get $all_nine)   ;; 0x... 09 09 09 09 09 09 09               )             )             (local.get $off)             ;; off = 1           )           (i32.const 0xFFFFFFFF)         ;; 0b...  1  1  1  1  1  1  1         )       )     )      ;; clean &amp; reverse     (local.set $xword       (v128.and                          ;; 0x... 00 00 01 02 03 04 05         (i8x16.swizzle                   ;; 0x... 00 00 31 32 33 34 35           (local.get $xword)             ;; 0x... 20 35 34 33 32 31 3D           (i8x16.add_sat_u               ;; 0x... FF FF 01 02 03 04 05             (i8x16.sub                   ;; 0x... FF FF 00 01 02 03 04               (global.get $shuf_reverse) ;; 0x... 09 0A 0B 0C 0D 0E 0F               (i8x16.splat               ;; 0x... 0B 0B 0B 0B 0B 0B 0B                 (i32.sub                 ;; = 0x0B                   (i32.const 16)                   (local.get $xn)        ;; xn = 5                 )               )             )             (i8x16.splat                 ;; 0x... 01 01 01 01 01 01 01               (local.get $off)           ;; off = 1             )           )         )         (global.get $all_digit)          ;; 0x... 0F 0F 0F 0F 0F 0F 0F       )     )      ;; i16x8.extmul_low_i8x16_u - not implemented     (local.set $xtempL       (i16x8.mul                  ;; H000 G00  F0   E  D000 C00  B0   A         (i16x8.widen_low_i8x16_u  ;;  0 H|0 G|0 F|0 E | 0 D|0 C|0 B|0 A           (local.get $xword)      ;;                ... H G F E D C B A         )         (global.get $stepA_pow10) ;; 1000 100  10   1  1000 100  10   1       )     )      ;; i32x4.extadd_pairwise_i16x8_u - not implemented     (local.set $xtempL       (i16x8.add                  ;; H000 HG00   F0   FE D000 DC00   B0   BA         (i32x4.shr_u              ;;    0 H000    0   F0    0 D000    0   B0           (local.get $xtempL)     ;; H000  G00   F0    E D000  C00   B0    A           (i32.const 16)         )         (local.get $xtempL)       ;; H000  G00   F0    E D000  C00   B0    A       )     )          (local.set $xtempH       (i16x8.mul                  ;; P000 O00  N0   M  L000 K00  J0   I         (i16x8.widen_high_i8x16_u ;;  0 P|0 O|0 N|0 M | 0 L|0 K|0 J|0 I           (local.get $xword)      ;;  P O N M L K J I ...         )                                                                       (global.get $stepA_pow10) ;; 1000 100  10   1  1000 100  10   1       )                                )      (local.set $xtempH       (i16x8.add                  ;; P000 PO00   N0   NM L000 LK00   J0   JI         (i32x4.shr_u              ;;    0 P000    0   N0    0 L000    0   J0           (local.get $xtempH)     ;; P000  O00   N0    M L000  K00   J0    I           (i32.const 16)         )         (local.get $xtempH)       ;; P000  O00   N0    M L000  K00   J0    I       )     )      ;; shuffle     (local.set $xword       (i8x16.shuffle              ;; PO00   NM LK00   JI HG00   FE DC00   BA         0x00 0x01 0x04 0x05 0x08 0x09 0x0C 0x0D 0x10 0x11 0x14 0x15 0x18 0x19 0x1C 0x1D          (local.get $xtempL)       ;; H000 HG00   F0   FE D000 DC00   B0   BA         (local.get $xtempH)       ;; P000 PO00   N0   NM L000 LK00   J0   JI       )     )      (local.set $xword       (i16x8.add                  ;; PO00 PONM LK00 LKJI HG00 HGFE DC00 DCBA         (i32x4.shr_u              ;;    0 PO00    0 LK00    0 HG00    0 DC00           (local.get $xword)      ;; PO00   NM LK00   JI HG00   FE DC00   BA           (i32.const 16)         )         (local.get $xword)        ;; PO00   NM LK00   JI HG00   FE DC00   BA       )     )      (local.set $xword       (v128.and                   ;;    0 PONM    0 LKJI    0 HGFE    0 DCBA         (local.get $xword)        ;; PO00 PONM LK00 LKJI HG00 HGFE DC00 DCBA         (global.get $stepA_mask)  ;; 0000 FFFF 0000 FFFF 0000 FFFF 0000 FFFF 0x...       )     )      (local.set $xword       (i32x4.mul                  ;;         0 LKJI00000000  HGFE0000     DCBA         (local.get $xword)        ;;    0 PONM       0 LKJI    0 HGFE   0 DCBA         (global.get $stepB_pow10) ;;         0    100000000     10000        1       )                                )      (local.set $xword       (i32x4.add                  ;;         0 LKJI00000000  HGFE0000 HGFEDCBA         (i64x2.shr_u              ;;         0            0         0 HGFE0000           (local.get $xword)      ;;         0 LKJI00000000  HGFE0000     DCBA           (i32.const 32)         )         (local.get $xword)        ;;         0 LKJI00000000  HGFE0000     DCBA       )     )      (local.set $xword       (v128.and                   ;;         0 LKJI00000000         0 HGFEDCBA         (local.get $xword)        ;;         0 LKJI00000000  HGFE0000 HGFEDCBA         (global.get $stepB_mask)  ;;  00000000     FFFFFFFF  00000000 FFFFFFFF 0x...       )     )      (global.set $val       (i64.add         (i64x2.extract_lane           0           (local.get $xword)         )         (i64x2.extract_lane           1           (local.get $xword)         )       )     )          ;; return     (local.get $xn)   )    (func (export \"parseBuffers\") (result i32)     (local $ch i32)      (local $chp i32)     (local $chv i32)     (local $chm i32)     (local $chi i32)      (local $ln i32)     (local $chpos i32)     (local $xword v128)     (local $xn i32)     (local $xbp i32)     (local $eol i32)     (local $esp i32)     (local $vtemp i64)      (local $mask i32)     (local $state i32)     (local $key i32)      ;; mask = 0     (local.set $mask       (i32.const 0)     )     ;; val = 0     (global.set $val       (i64.const 0)     )     ;; off += 'Buffers: '.length     (global.set $off       (i32.add         (global.get $off)         (i32.const 9)       )     )     ;; \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0432\u0441\u0435\u0433\u0434\u0430 \"\u043f\u043e\u0441\u043b\u0435\u043f\u0440\u043e\u0431\u0435\u043b\u044c\u043d\u044b\u0439\"     (local.set $esp       (i32.const 1)     )     (local.set $xbp       (i32.const -1)     )     ;; for (...)     (block       (loop         ;; xword = line[off..+15]         (local.set $xword           (v128.load align=4             (global.get $off)           )         )          ;; xbp == -1 -&gt; \u043d\u0435 \u043f\u0430\u0440\u0441\u0438\u043c \u0441\u0435\u0439\u0447\u0430\u0441 \u0447\u0438\u0441\u043b\u043e         ;; xbp &gt;=  0 -&gt; \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442\u0441\u044e\u0434\u0430 \u0438 \u043f\u0430\u0440\u0441\u0438\u043c         (if           (i32.ne             (local.get $xbp)             (i32.const -1)           )           (then             ;; store temp             (local.set $vtemp               (global.get $val)             )              ;; xn = num digits             (local.set $xn               (call $parseNumber                 (local.get $xword)                 (local.get $xbp)               )             )              (if               (i32.eqz                 (local.get $xbp)               )               (then                 ;; val = val * 10 ^ memory[128 + (n &lt;&lt; 3)]:i32 + vtemp                 (global.set $val                   (i64.add                     (i64.mul                       (local.get $vtemp)                       (i64.load align=4                         (i32.add                           (i32.shl                             (local.get $xn)                             (i32.const 3)                           )                           (i32.const 128)                         )                       )                     )                     (global.get $val)                   )                 )               )             )              ;; store value             (local.set $mask               (call $setData                 (local.get $key)                 (local.get $mask)               )             )              ;; xbp = -1             (local.set $xbp               (i32.const -1)             )           )         )          ;; off += 16         (global.set $off           (i32.add             (global.get $off)             (i32.const 16)           )         )          ;; \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0431\u0438\u0442\u043e\u0432\u0443\u044e \u043c\u0430\u0441\u043a\u0443 \"\u043f\u043e\u0441\u043b\u0435\u043f\u0440\u043e\u0431\u0435\u043b\u044c\u043d\u044b\u0445\" \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432         (local.set $chm           (i32.and             (i32.add               (i32.shl                 ;; space mask                 (i8x16.bitmask                   (i8x16.eq                     (local.get $xword)                     (global.get $all_space)                   )                 )                 (i32.const 1)               )               ;; \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430, \u0447\u0442\u043e \u043e\u043d \"\u043f\u043e\u0441\u043b\u0435\u043f\u0440\u043e\u0431\u0435\u043b\u044c\u043d\u044b\u0439\",               ;; \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0431\u0435\u043b \u0431\u044b\u043b \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430               (local.get $esp)             )             (i32.const 0xFFFF)           )         )          ;; \u043f\u043e \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0431\u0438\u0442\u043e\u0432\u0443\u044e \u043c\u0430\u0441\u043a\u0443 \u0432 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0431\u0438\u0442\u043e\u0432         ;; shared hit=1 read         ;; 1000000100000100 =&gt; 0x FF 0D 07 00         ;; chp = memory[0x10000 + (chm &lt;&lt; 2)]:i32         (local.set $chp           (i32.load align=4             (i32.add               (i32.const 0x10000)               (i32.shl                 (local.get $chm)                 (i32.const 2)               )             )           )         )         ;; \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0432 \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f         (local.set $chv           (i32x4.extract_lane             0             (i8x16.swizzle               (local.get $xword)               (i32x4.replace_lane                 0                 (i8x16.splat                   (i32.const 0xFF)                 )                 (local.get $chp)               )             )           )         )          ;; \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0431\u0438\u0442\u0430\u043c \u043c\u0430\u0441\u043a\u0438, \u043f\u043e\u043a\u0430 \u043e\u043d\u0430 \u043d\u0435 \u043e\u0431\u043d\u0443\u043b\u0438\u0442\u0441\u044f         (block           (loop             ;; if (chv == 0) break             (br_if 1               (i32.eqz                 (local.get $chv)               )             )              (local.set $chpos               (i32.and                 (local.get $chp)                 (i32.const 0xFF)               )             )              ;; ch = xword[chpos]             (local.set $ch               (i32.and                 (local.get $chv)                 (i32.const 0xFF)               )             )              ;; ch = memory[0xC0 + ch]             (local.set $ch               (i32.load align=4                 (i32.add                   (i32.shl                     (local.get $ch)                     (i32.const 2)                   )                   (i32.const 0xC0)                 )               )             )              ;; ln = ch &gt;&gt; 8             (local.set $ln               (i32.shr_u                 (local.get $ch)                 (i32.const 8)               )             )              ;; \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0447\u0438\u0441\u043b\u0430, \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u0440\u0448\u0435\u043c \u0431\u0430\u0439\u0442\u0435 ch             (local.set $xbp               (i32.and                 (i32.add                   (local.get $chpos)                   (local.get $ln)                 )                 (i32.const 0xFF)               )             )              ;; ch &amp; 0x10000             (if               (i32.eqz                 (i32.and                   (local.get $ch)                   (i32.const 0x10000)                 )               )               ;; key               (then                 (local.set $key                   (i32.and                     (i32.add                       (local.get $state)                       (local.get $ch)                     )                     (i32.const 0x0F)                   )                 )                  ;; \u0435\u0441\u043b\u0438 \u0447\u0438\u0441\u043b\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0431\u043b\u043e\u043a\u0435 - \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043d\u0435\u043c\u0443                 (if                   (i32.ge_u                     (local.get $xbp)                     (i32.const 0x10)                   )                   (then                     ;; val = 0                     (global.set $val                       (i64.const 0)                     )                     ;; xbp -= 16                     (local.set $xbp                       (i32.and                         (local.get $xbp)                         (i32.const 0x0F)                       )                     )                     (br 1)                   )                 )                  ;; xn = num digits                 (local.set $xn                   (call $parseNumber                     (local.get $xword)                     (local.get $xbp)                   )                 )                  ;; xbp = xbp + xn == 0x10 ? 0 : -1                 (local.set $xbp                   (if (result i32)                     (i32.eq                       (i32.add                         (local.get $xbp)                         (local.get $xn)                       )                       (i32.const 0x10)                     )                     (then                       (i32.const 0)                     )                     (else                       ;; store value                       (local.set $mask                         (call $setData                           (local.get $key)                           (local.get $mask)                         )                       )                       (i32.const -1)                     )                   )                 )               )               ;; state               (else                 (local.set $state                   (i32.and                     (local.get $ch)                     (i32.const 0x0F)                   )                 )               )             )              ;; chv &gt;&gt;= 8             (local.set $chv               (i32.shr_u                 (local.get $chv)                 (i32.const 8)               )             )             ;; chp &gt;&gt;= 8             (local.set $chp               (i32.shr_u                 (local.get $chp)                 (i32.const 8)               )             )                          ;; do loop             (br 0)           )         )          ;; esp = xword[15] == 0x20         (local.set $esp           (i32.eq             (i8x16.extract_lane_u               15               (local.get $xword)             )             (i32.const 0x20)           )         )          ;; check EOL         (local.set $eol           (i8x16.bitmask             (i8x16.eq               (local.get $xword)               (global.get $all_0A)             )           )         )          ;; if (!eol) break         (br_if 0           (i32.eqz             (local.get $eol)           )         )          ;; break, end loop          ;; store value         (local.set $mask           (call $setData             (local.get $key)             (local.get $mask)           )         )          ;; \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u0441\u0442\u0440\u043e\u043a\u0438         (local.set $eol           (i32.ctz             (local.get $eol)           )         )          ;; \u0432\u0441\u0442\u0430\u0435\u043c \u043d\u0430 \u043d\u0430\u0447\u0430\u043b\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0438         ;; off += 15 - eol         (global.set $off           (i32.sub             (i32.add               (global.get $off)               (local.get $eol)             )             (i32.const 15)           )         )          ;; break         (br 1)       )     )      ;; \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435     (i32.store       (i32.const 0xFFFC) ;; 16383 * 4       (global.get $off)     )     ;; \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043c\u0430\u0441\u043a\u0443     (local.get $mask)   ) )<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0423\u0432\u044b, \u0432\u0441\u0435 \u044d\u0442\u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043e\u0431\u043e\u0433\u043d\u0430\u0442\u044c SWAR-\u043a\u043e\u0434 \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0430 \u043b\u0438\u0448\u044c \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043f\u0430\u0440\u0438\u0442\u0435\u0442\u0430 \u0441 \u043d\u0438\u043c.<\/p>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c, \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 SIMD \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0430\u043b\u043e\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u043c, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <strong>\u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u0437\u043d\u0430\u0447\u0438\u043c\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u0435\u043b\u0438\u043a\u0438, \u0430 \u0441\u0430\u043c\u0430 \u043e\u043d\u0430 \u043c\u0430\u043b\u0430<\/strong>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u043b\u0438\u043d\u043e\u0439 47 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432\u0441\u0435\u0433\u043e 11 \u0438\u0437 \u043d\u0438\u0445:<\/p>\n<pre><code>Buffers: shared hit=123 read=45, temp written=6          ^      ^   *** ^    **  ^    ^       *<\/code><\/pre>\n<hr>\n<p>\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md\">WebAssembly 128-bit packed SIMD Extension<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/ImplementationStatus.md\">WASM SIMD Implementation Status<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/webassembly.github.io\/wabt\/demo\/wat2wasm\/\">wat2wasm demo<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/stackoverflow.com\/questions\/35127060\/how-to-implement-atoi-using-simd\">StackOverflow: How to implement atoi using SIMD?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/v8.dev\/features\/simd\">V8 blog: Fast, parallel applications with WebAssembly SIMD<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/tensor\/blog\/545642\/\"> https:\/\/habr.com\/ru\/company\/tensor\/blog\/545642\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/post\/545272\/\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u043c\u044b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u043d\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e SWAR-\u0445\u0438\u043d\u0442\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 8 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0446\u0438\u0444\u0440 \u0432 \u043e\u0434\u043d\u043e \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0435 32bit-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041d\u043e \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0443 \u043d\u0430\u0441, \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c, \u043d\u0435\u0432\u0435\u043b\u0438\u043a\u0438 &#8212; \u0434\u043e 3 \u0446\u0438\u0444\u0440? \u0422\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u0432\u043f\u043e\u043b\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e <strong>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c 32bit-\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438<\/strong>, \u0430 SWAR \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u0437\u0430 2 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u043c\u0435\u0441\u0442\u043e 3 &#8212; \u0441\u043f\u043b\u043e\u0448\u043d\u043e\u0439 \u0432\u044b\u0438\u0433\u0440\u044b\u0448!<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0448 \u043a\u043e\u0434 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0432\u044b\u0439 \u0431\u043b\u043e\u043a \u0438\u0437 4 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0441\u044f 32bit-\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438, \u0430 \u0435\u0441\u043b\u0438 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0432\u0442\u043e\u0440\u043e\u0439 \u0431\u043b\u043e\u043a \u0438\u0437 8 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 &#8212; \u0443\u0436\u0435 64bit-\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438.<\/p>\n<p>\u0418&#8230; \u0432\u043c\u0435\u0441\u0442\u043e 26ms \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c <strong>28ms<\/strong>! \u0417\u043d\u0430\u0447\u0438\u0442, \u043d\u0430\u0448\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u0438\u043d\u044b \u0447\u0438\u0441\u0435\u043b \u043d\u0435 \u043e\u043f\u0440\u0430\u0432\u0434\u0430\u043b\u043e\u0441\u044c, \u0438 \u0432 \u043f\u0435\u0440\u0432\u043e\u043c \u0431\u043b\u043e\u043a\u0435 \u0432\u044b\u0433\u043e\u0434\u043d\u0435\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<figure class=\"full-width\"><figcaption>\u0431\u043e\u043b\u044c\u0448\u0438\u0435 &#8212; \u043d\u043e \u043f\u043e 5, \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0435 &#8212; \u043d\u043e \u043f\u043e 3<\/figcaption><\/figure>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430 &#8212; \u043b\u0443\u0447\u0448\u0435? \u0418 \u0442\u0430\u043a\u0438\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b \u0435\u0441\u0442\u044c &#8212; \u044d\u0442\u043e 128-\u0431\u0438\u0442\u043d\u044b\u0435 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/SSE\">SSE-\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b<\/a> <strong>XMM &#8212; \u0432 WebAssembly<\/strong> \u043e\u043d\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043d\u0430\u043c \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441 \u0442\u0438\u043f\u043e\u043c <code>v128<\/code> \u0438 <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md\">\u0441\u0443\u043f\u0435\u0440\u0441\u043a\u0430\u043b\u044f\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \u043d\u0438\u043c\u0438<\/a>.<\/p>\n<blockquote>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u043e\u043a\u0430 <strong>\u043d\u0435 \u0432\u0441\u0435<\/strong> \u044d\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/ImplementationStatus.md\">\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 JavaScript-\u0434\u0432\u0438\u0436\u043a\u0430\u0445<\/a>.<\/p>\n<\/blockquote>\n<p>\u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 <code>v128<\/code>-\u0440\u0435\u0433\u0438\u0441\u0442\u0440 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043b\u0438\u0431\u043e \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u044b\u0439 \u0431\u043b\u043e\u043a (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0431\u0438\u0442\u043e\u0432\u044b\u0445 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 <code>and, or, xor, not<\/code>), \u043b\u0438\u0431\u043e \u043a\u0430\u043a \u043d\u0430\u0431\u043e\u0440 \u0431\u043b\u043e\u043a\u043e\u0432 \u043c\u0435\u043d\u044c\u0448\u0435\u0439 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u0438:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h2>\u041a\u0430\u043a \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c SIMD \u0432 Node.js<\/h2>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0448 &#171;\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440&#187; <code>compile-test.js<\/code>: \u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"javascript\">const wasmModule = wabt.parseWat(   inputWat , readFileSync(inputWat, 'utf8') , {simd : true} \/\/ \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 SIMD-feature );<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u0440\u0443\u0433\u0438\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 &#171;\u0444\u0438\u0447\u0438&#187; \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 WASM \u043c\u043e\u0436\u043d\u043e \u043d\u0430 <a href=\"https:\/\/webassembly.github.io\/wabt\/demo\/wat2wasm\/\">\u0434\u0435\u043c\u043e-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 wat2wasm<\/a>.<\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 Node.js \u043f\u043e\u043a\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 SIMD \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430\u0448 \u043f\u0430\u0440\u0441\u0435\u0440 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 <a href=\"https:\/\/nodejs.org\/api\/cli.html#cli_v8_options\">V8-\u043e\u043f\u0446\u0438\u044f\u043c\u0438<\/a>:<\/p>\n<pre><code>  --experimental-wasm-simd (enable prototype SIMD opcodes for wasm)         type: bool  default: false   --wasm-simd-post-mvp (allow experimental SIMD operations for prototyping that are not included in the current proposal)         type: bool  default: false<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0430 \u0437\u0430\u043f\u0443\u0441\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"bash\">node --experimental-wasm-simd --wasm-simd-post-mvp --expose-gc buffers-test.js<\/code><\/pre>\n<h2>SIMD-\u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043d\u0430\u0442\u0443\u0440\u0430\u043b\u044c\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u043d\u0430 WASM<\/h2>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u0442\u0435 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0447\u0442\u043e \u0438 \u0434\u043b\u044f SWAR-\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u043d\u043e \u0443\u0436\u0435 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 <code>v128<\/code>-\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439. \u0417\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0432\u043e\u0437\u044c\u043c\u0435\u043c <a href=\"https:\/\/stackoverflow.com\/questions\/35127060\/how-to-implement-atoi-using-simd\">\u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u043d\u0430 StackOverflow<\/a>.<\/p>\n<h4>\u0423\u0437\u043d\u0430\u0435\u043c \u0434\u043b\u0438\u043d\u0443 \u0447\u0438\u0441\u043b\u0430<\/h4>\n<ol>\n<li>\n<p>\u0432\u044b\u0447\u0438\u0442\u0430\u0435\u043c &#171;\u043d\u0443\u043b\u0435\u0432\u043e\u0439&#187; \u0441\u0438\u043c\u0432\u043e\u043b <code>0x30<\/code> \u0438\u0437 \u043a\u0430\u0436\u0434\u043e\u0433\u043e, <strong>\u0441 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u0447\u0435\u0440\u0435\u0437 0<\/strong> &#8212; \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0430\u0448\u0438 \u0441\u0442\u043e\u043f-\u0441\u0438\u043c\u0432\u043e\u043b\u044b <code>0x0A, 0x20 \u0438 0x2C<\/code> \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u044f\u0442\u0441\u044f \u0432 <code>0xDA, 0xF0 \u0438 0xFC<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u0430\u0439\u0442\u0430, \u0447\u0442\u043e \u043e\u043d <code>&lt;= 0x09<\/code> &#8212; \u0442\u043e \u0435\u0441\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0441\u044f \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 <code>0x30..0x39<\/code>, \u0447\u0442\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c <code>'0'..'9'<\/code><\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043f\u0435\u0440\u0432\u044b\u0439 <code>false<\/code>-\u0431\u0430\u0439\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>ctz(not(bitmask))<\/code> &#8212; \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0442\u043e\u043f-\u0441\u0438\u043c\u0432\u043e\u043b\u0430<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0432 \u043a\u043e\u0434\u0435 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0434\u0432\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435-&#171;\u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b&#187;: &#171;\u0432\u0441\u0435 \u043d\u0443\u043b\u0438&#187; \u0438 &#171;\u0432\u0441\u0435 \u0434\u0435\u0432\u044f\u0442\u043a\u0438&#187;:<\/p>\n<pre><code class=\"javascript\">  (global $all_zero v128     (v128.const i8x16 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30)   )   (global $all_nine v128     (v128.const i8x16 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09)   )<\/code><\/pre>\n<pre><code class=\"javascript\">  ;; \u0440\u0430\u0437\u0431\u043e\u0440 \u0447\u0438\u0441\u043b\u0430 - SIMD   (func $parseNumber     (local $ch i32)     (local $xword v128)     (local $xn i32)      ;; xword = line[off..+15]     (local.set $xword       (v128.load align=4         (global.get $off)       )     )      ;; xn = num digits     (local.set $xn       (i32.ctz                         ;;        * = 5         (i32.xor                       ;; 0b...  1  0  0  0  0  0           (i8x16.bitmask               ;; 0b...  0  1  1  1  1  1             (i8x16.le_u                ;; 0x... 00 FF FF FF FF FF               (i8x16.sub               ;; 0x... F0 05 04 03 02 01                 (local.get $xword)     ;; 0x... 20 35 34 33 32 31                 (global.get $all_zero) ;; 0x... 30 30 30 30 30 30                )               (global.get $all_nine)   ;; 0x... 09 09 09 09 09 09             )           )           (i32.const 0xFFFFFFFF)       ;; 0b...  1  1  1  1  1  1         )       )     )<\/code><\/pre>\n<h4>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0441\u0442\u043e\u043f-\u0441\u0438\u043c\u0432\u043e\u043b<\/h4>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u0432\u0437\u044f\u0442\u044c <code>xn<\/code>-\u0439 \u0431\u0430\u0439\u0442 \u0438\u0437 v128-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u043b\u044c\u0437\u044f &#8212; \u043d\u0435\u0442 <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md#accessing-lanes\">\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438<\/a>. \u0417\u0430\u0442\u043e \u0435\u0441\u0442\u044c <code>i8x16.extract_lane<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u0437\u044f\u0442\u044c \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0431\u0430\u0439\u0442 (\u043d\u0430\u0441 \u0432\u043f\u043e\u043b\u043d\u0435 \u0443\u0441\u0442\u0440\u043e\u0438\u0442 <code>#0<\/code>).<\/p>\n<p>\u041d\u043e \u0447\u0442\u043e\u0431\u044b \u0432 \u043d\u0443\u043b\u0435\u0432\u043e\u043c \u0431\u0430\u0439\u0442\u0435 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f <code>xn<\/code>-\u0439, \u043d\u0443\u0436\u043d\u043e <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md#swizzling-using-variable-indices\">&#171;\u043f\u0435\u0440\u0435\u043b\u043e\u0436\u0438\u0442\u044c&#187; \u0431\u0430\u0439\u0442\u044b<\/a> \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u043c\u0430\u0441\u043a\u043e\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>swizzle<\/code>.<\/p>\n<p>\u0410 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043c\u0430\u0441\u043a\u0443, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0443\u044e <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md#create-vector-with-identical-lanes\">\u0438\u0437 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/a> <code>xn<\/code>, \u043d\u0430\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f <code>splat<\/code>.<\/p>\n<pre><code class=\"javascript\">    ;; ch = xword[xn]     (local.set $ch           ;; ch = 0x20       (i8x16.extract_lane_u  ;; xmm[0]         0                    ;; \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430         (i8x16.swizzle       ;; 0x... 20 20 20 20 20 20           (local.get $xword) ;; 0x... 20 35 34 33 32 31           (i8x16.splat       ;; 0x... 05 05 05 05 05 05             (local.get $xn)  ;; xn = 5           )         )       )     )<\/code><\/pre>\n<h4>\u041d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0447\u0438\u0441\u043b\u043e<\/h4>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>swizzle<\/code> &#171;\u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0435\u043c&#187; \u0447\u0438\u0441\u043b\u043e, \u0447\u0442\u043e\u0431\u044b \u043c\u043b\u0430\u0434\u0448\u0438\u0439 \u0440\u0430\u0437\u0440\u044f\u0434 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0432 \u043c\u043b\u0430\u0434\u0448\u0435\u043c \u0431\u0430\u0439\u0442\u0435, \u0438 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u0447\u0438\u0441\u0442\u0438\u043c \u043e\u0442 \u043d\u0435-\u0446\u0438\u0444\u0440 <strong>\u0437\u0430 \u0441\u0447\u0435\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u044d\u0442\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 &#171;\u0437\u0430\u043d\u0443\u043b\u044f\u0442\u044c&#187; \u0431\u0430\u0439\u0442\u044b<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0431\u043e\u043b\u044c\u0448\u0435 <code>0x0F<\/code>.<\/p>\n<pre><code class=\"javascript\">  (global $shuf_reverse v128     (v128.const i8x16 0x0F 0x0E 0x0D 0x0C 0x0B 0x0A 0x09 0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01 0x00)   )   (global $all_digit v128     (v128.const i8x16 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F)   )<\/code><\/pre>\n<pre><code class=\"javascript\">    ;; clean &amp; reverse     (local.set $xword       (v128.and                        ;; 0x... 00 01 02 03 04 05         (i8x16.swizzle                 ;; 0x... 00 31 32 33 34 35           (local.get $xword)           ;; 0x... 20 35 34 33 32 31           (i8x16.sub                   ;; 0x... FF 00 01 02 03 04             (global.get $shuf_reverse) ;; 0x... 0A 0B 0C 0D 0E 0F             (i8x16.splat               ;; 0x... 0B 0B 0B 0B 0B 0B               (i32.sub                 ;; = 0x0B                 (i32.const 16)                 (local.get $xn)        ;; xn = 5               )             )           )         )         (global.get $all_digit)        ;; 0x... 0F 0F 0F 0F 0F 0F       )     )<\/code><\/pre>\n<h4>SIMD-\u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f<\/h4>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 (\u0447\u0438\u0442\u0430\u0439, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430), \u043a\u043e\u0433\u0434\u0430 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0437 16 \u0431\u0430\u0439\u0442\u043e\u0432 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f <strong>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0446\u0438\u0444\u0440<\/strong>, \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0435\u0441\u044f\u0442\u0438\u0447\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u044f\u0434\u0430\u043c \u0447\u0438\u0441\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c &#8212; \u0432 \u043c\u043b\u0430\u0434\u0448\u0435\u043c \u0431\u0430\u0439\u0442\u0435 \u043c\u043b\u0430\u0434\u0448\u0438\u0439 \u0440\u0430\u0437\u0440\u044f\u0434:<\/p>\n<pre><code>P O N M L K J I H G F E D C B A == A * 10^0 + B * 10^1 + C * 10^2 + D * 10^3 + ...<\/code><\/pre>\n<p>\u0412 \u0438\u0434\u0435\u0430\u043b\u0435, \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043d\u0430\u043c \u043f\u043e\u0434\u043e\u0448\u043b\u0438 \u0431\u044b <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md#extended-integer-multiplication\">\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f<\/a> \u0442\u0438\u043f\u0430 <code>i16x8.extmul_[low|high]_i8x16_u<\/code> \u0438 <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/SIMD.md#extended-pairwise-integer-addition\">\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043f\u0430\u0440\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/a> <code>i16x8.extadd_pairwise_i8x16_u<\/code>.<\/p>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0438\u0437 \u044d\u0442\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0443\u043c\u043d\u043e\u0436\u0430\u0435\u0442 \u043d\u0438\u0436\u043d\u0438\u0435\/\u0432\u0435\u0440\u0445\u043d\u0438\u0435 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u044b \u043f\u0430\u0440\u044b XMM-\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432, \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044f \u0438\u0445 \u043a\u0430\u043a \u043d\u0430\u0431\u043e\u0440 8bit-\u0447\u0438\u0441\u0435\u043b \u043d\u0430 \u0432\u0445\u043e\u0434\u0435, \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u044f \u0432\u044b\u0445\u043e\u0434 \u0434\u043e 16bit-\u0447\u0438\u0441\u0435\u043b:<\/p>\n<pre><code>0x...   FC   FD   FE   FF          x    x    x    x 0x...   04   03   02   01          =    =    =    = 0x... 03F0 02F7 01FC 00FF = i16x8.extmul_low_i8x16_u<\/code><\/pre>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043f\u0430\u0440\u043d\u043e \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 &#171;\u0447\u0438\u0441\u043b\u0430&#187; \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435:<\/p>\n<pre><code>0x... FC + FD   FE + FF 0x...    01F9      01FD = i16x8.extadd_pairwise_i8x16_u<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <a href=\"https:\/\/github.com\/WebAssembly\/simd\/blob\/master\/proposals\/simd\/ImplementationStatus.md\">\u043e\u043d\u0438 \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f<\/a>, \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0438\u0445 \u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0432\u044b\u0434\u0435\u043b\u0438\u043c \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>i16x8.widen_low_i8x16_u<\/code>  \u043d\u0438\u0436\u043d\u044e\u044e \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0443, \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0432 8bit-\u0447\u0438\u0441\u043b\u0430 \u0434\u043e 16bit \u0438 \u043f\u0435\u0440\u0435\u043c\u043d\u043e\u0436\u0438\u043c \u0441 \u043c\u0430\u0441\u043a\u043e\u0439 \u0441\u0442\u0435\u043f\u0435\u043d\u0435\u0439 10:<\/p>\n<pre><code class=\"javascript\">  (global $stepA_pow10 v128     (v128.const i16x8 1 10 100 1000 1 10 100 1000)   ) ;; ...     ;; i16x8.extmul_low_i8x16_u - not implemented     (local.set $xtempL       (i16x8.mul                  ;; H000 G00  F0   E  D000 C00  B0   A         (i16x8.widen_low_i8x16_u  ;;  0 H|0 G|0 F|0 E | 0 D|0 C|0 B|0 A           (local.get $xword)      ;;                ... H G F E D C B A         )         (global.get $stepA_pow10) ;; 1000 100  10   1  1000 100  10   1       )     )<\/code><\/pre>\n<p>\u0421\u0442\u0435\u043f\u0435\u043d\u0438 \u0432\u044b\u0431\u0440\u0430\u043d\u044b \u0441 \u0442\u0430\u043a\u0438\u043c \u0443\u043c\u044b\u0441\u043b\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0438 \u0432 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 16bit-\u044f\u0447\u0435\u0435\u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0435 \u043c\u043e\u0433 \u043f\u0440\u0435\u0432\u0437\u043e\u0439\u0442\u0438 2^16.<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u044d\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u043c <code>extadd_pairwise<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0438\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0434\u0432\u0438\u0433\u0430, \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438, \u043a\u043e\u0433\u0434\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0438\u0442\u043e\u0432\u043e\u0439 \u043c\u0430\u0441\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">    ;; i32x4.extadd_pairwise_i16x8_u - not implemented     (local.set $xtempL       (i16x8.add                  ;; H000 HG00   F0   FE D000 DC00   B0   BA         (i32x4.shr_u              ;;    0 H000    0   F0    0 D000    0   B0           (local.get $xtempL)     ;; H000  G00   F0    E D000  C00   B0    A           (i32.const 16)         )         (local.get $xtempL)       ;; H000  G00   F0    E D000  C00   B0    A       )     )<\/code><\/pre>\n<p>\u0422\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u043e \u0441\u0442\u0430\u0440\u0448\u0438\u043c\u0438 \u0431\u0430\u0439\u0442\u0430\u043c\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430:<\/p>\n<pre><code class=\"javascript\">    (local.set $xtempH       (i16x8.mul                  ;; P000 O00  N0   M  L000 K00  J0   I         (i16x8.widen_high_i8x16_u ;;  0 P|0 O|0 N|0 M | 0 L|0 K|0 J|0 I           (local.get $xword)      ;;  P O N M L K J I ...         )                                                                       (global.get $stepA_pow10) ;; 1000 100  10   1  1000 100  10   1       )                                )      (local.set $xtempH       (i16x8.add                  ;; P000 PO00   N0   NM L000 LK00   J0   JI         (i32x4.shr_u              ;;    0 P000    0   N0    0 L000    0   J0           (local.get $xtempH)     ;; P000  O00   N0    M L000  K00   J0    I           (i32.const 16)         )         (local.get $xtempH)       ;; P000  O00   N0    M L000  K00   J0    I       )     )<\/code><\/pre>\n<p>\u0423\u043f\u0430\u043a\u0443\u0435\u043c \u043e\u0431\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u043e\u0434\u0438\u043d \u0440\u0435\u0433\u0438\u0441\u0442\u0440, \u043e\u0442\u0431\u0440\u043e\u0441\u0438\u0432 \u043b\u0438\u0448\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>shuffle<\/code>:<\/p>\n<pre><code class=\"javascript\">    ;; shuffle     (local.set $xword       (i8x16.shuffle              ;; PO00   NM LK00   JI HG00   FE DC00   BA         0x00 0x01 0x04 0x05 0x08 0x09 0x0C 0x0D 0x10 0x11 0x14 0x15 0x18 0x19 0x1C 0x1D          (local.get $xtempL)       ;; H000 HG00   F0   FE D000 DC00   B0   BA         (local.get $xtempH)       ;; P000 PO00   N0   NM L000 LK00   J0   JI       )     )<\/code><\/pre>\n<p>\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u043c \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435-\u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0445 \u0431\u043b\u043e\u043a\u043e\u0432 \u0435\u0449\u0435 \u0434\u0432\u0430\u0436\u0434\u044b &#8212; \u0434\u043b\u044f i16x8 \u0438 i32x4, \u0443\u0436\u0435 \u0441 \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043c\u0430\u0441\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">  (global $stepB_pow10 v128     (v128.const i32x4 1 10000 100000000 0)   )   (global $stepB_mask v128     (v128.const i32x4 0xFFFFFFFF 0x00000000 0xFFFFFFFF 0x00000000)   ) ;; ...<\/code><\/pre>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-319468","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/319468","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=319468"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/319468\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=319468"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=319468"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=319468"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}