<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          WebAssembly 基礎(chǔ)

          共 4698字,需瀏覽 10分鐘

           ·

          2021-10-23 12:18

          WebAssembly 介紹

          官網(wǎng)介紹:?WebAssembly?或者?wasm?是一個(gè)可移植、體積小、加載快并且兼容 Web 的全新格式。分析一下?WebAssembly?這個(gè)詞由?Web?和?Assembly?組成,?Web?代表和前端有關(guān),?Assembly?匯編的意思,匯編對(duì)應(yīng)著機(jī)器碼,而機(jī)器碼對(duì)應(yīng)著指令集,那么什么是指令集呢?先來看一張圖片圖片來自?WebAssembly入門-未來可能發(fā)生的巨變[1]?參考上圖,計(jì)算機(jī)的主要架構(gòu)如上。最底層是?CPU?的指令集,主要分為復(fù)雜指令集和簡(jiǎn)單指令集。復(fù)雜指令集是?x86?、?x64(也叫 x86-64, amd64)?兩種架構(gòu),專利在?Intel?和?AMD?兩家公司手里, 該架構(gòu)?CPU?主要是?Intel?和?AMD?兩家公司,這種?CPU?常用在?PC?機(jī)上,包括?Windows?,?macOS?和?Linux?。簡(jiǎn)單指令集是?arm?一種架構(gòu),專利在?ARM?公司手里,該架構(gòu)?CPU?主要有高通、三星、蘋果、華為海思、聯(lián)發(fā)科等公司。這種?CPU?常用在手機(jī)上,包括安卓和蘋果。那么什么是指令集呢?直接把阮一峰的老師的一個(gè)?例子[2]?粘過來,大家可以看一下。?c?語言的源程序。

          int?add_a_and_b(int?a,?int?b)?{
          ?return?a?+?b;
          }

          int?main()?{
          ?return?add_a_and_b(2,?3);
          }

          所對(duì)應(yīng)的匯編就是下邊的樣子。

          _add_a_and_b:
          ?push?%ebx
          ?mov?%eax,?[%esp+8]
          ?mov?%ebx,?[%esp+12]
          ?add?%eax,?%ebx
          ?pop?%ebx
          ?ret?

          _main:
          ?push?3
          ?push?2
          ?call?_add_a_and_b
          ?add?%esp,?8
          ?ret

          這里的?push?、?mov?每一條指令就是指令集規(guī)定的內(nèi)容,規(guī)定了操作碼、操作數(shù)以及具體的功能。當(dāng)然這里是用匯編表示的,主要是為了我們?nèi)祟悂碜x寫,最終還會(huì)轉(zhuǎn)成?0,1?序列。上邊每個(gè)單詞都會(huì)有一個(gè)數(shù)字相對(duì)應(yīng),比如?add?指令對(duì)應(yīng)?00000011?。通過規(guī)定的指令集(加法的指令,壓棧指令等),編寫相關(guān)程序,然后?CPU?就會(huì)一條一條的執(zhí)行,最終實(shí)現(xiàn)相應(yīng)的功能。而?WebAssembly?就規(guī)定了一套指令集,更準(zhǔn)確的來說是虛擬指令集,因?yàn)檫@套指令集是跑在虛擬機(jī)上的,而不是直接由硬件運(yùn)行。(指令內(nèi)容來源自?WebAssembly入門-未來可能發(fā)生的巨變[3]?)

          簡(jiǎn)單來說就是,編譯器將?C++?,?Go?,?Rust?等編譯為中間代碼,再轉(zhuǎn)化為?WebAssembly?字節(jié)碼(類似java的字節(jié)碼),?WebAssembly?字節(jié)碼是一種抹平了不同?CPU?架構(gòu)的機(jī)器碼,?WebAssembly?字節(jié)碼不能直接在任何一種?CPU?架構(gòu)上運(yùn)行, 但由于非常接近機(jī)器碼,可以非??斓谋环g為對(duì)應(yīng)架構(gòu)的機(jī)器碼,因此?WebAssembly?運(yùn)行速度和機(jī)器碼接近。

          WebAssembly.compile(new?Uint8Array(`
          ??00?61?73?6d??01?00?00?00??01?0c?02?60??02?7f?7f?01
          ??7f?60?01?7f??01?7f?03?03??02?00?01?07??10?02?03?61
          ??64?64?00?00??06?73?71?75??61?72?65?00??01?0a?13?02
          ??08?00?20?00??20?01?6a?0f??0b?08?00?20??00?20?00?6c
          ??0f?0b`
          .trim().split(/[\s\r\n]+/g).map(str?=>?parseInt(str,?16))
          )).then(module?=>?{
          ??const?instance?=?new?WebAssembly.Instance(module)
          ??const?{?add,?square?}?=?instance.exports
          console.log('2?+?4?=',?add(2,?4))
          console.log('3^2?=',?square(3))
          console.log('(2?+?5)^2?=',?square(add(2?+?5)))})

          將上面代碼拷貝到瀏覽器控制臺(tái)就能看到結(jié)果。綜上所述可以知道wasm其實(shí)是一種二進(jìn)制字節(jié)碼,和機(jī)器碼比較類似,我們都知道匯編語言可以被轉(zhuǎn)化為機(jī)器碼,同樣wasm也有類似的匯編語言,被稱為?S-表達(dá)式?(?mdn定義[4]?),可以使用工具?wat2wasm?在?S-表達(dá)式?和?wasm?字節(jié)碼之間相互轉(zhuǎn)換

          WebAssembly 由來

          由于前端業(yè)務(wù)場(chǎng)景越來越多,業(yè)務(wù)越來越復(fù)雜,導(dǎo)致在一些性能比較差的機(jī)器上表現(xiàn)不好。表現(xiàn)不好一方面確實(shí)是業(yè)務(wù)場(chǎng)景比較復(fù)雜,另一方面就是?javascript?這門語言本身的缺陷。其一?javascript?是一門解釋型語言,首先解釋一下編譯型和解釋型編程語言的區(qū)別。編譯型:將源代碼經(jīng)過編譯器轉(zhuǎn)為機(jī)器碼,在執(zhí)行 解釋型:代碼運(yùn)行過程中,將源代碼經(jīng)過編譯器生成中間代碼,中間代碼再通過虛擬器生成目標(biāo)平臺(tái)的機(jī)器碼執(zhí)行。引用知乎上的一句話,編譯型就是提前做好一桌子菜,再吃,而解釋型就相當(dāng)于吃火鍋,一邊吃,一邊煮 所以說解釋型編譯語言會(huì)比編譯型語言慢些。個(gè)人認(rèn)為這個(gè)并不怎么影響性能。其二?javascript?是一門動(dòng)態(tài)語言編寫程序時(shí)無需考慮變量類型,對(duì)于開發(fā)人員確實(shí)友好,但是對(duì)于js引擎來說并不友好。在js引擎沒有引入JIT之前,假如一個(gè)方法被不同模塊調(diào)用10次,那么這個(gè)方法也會(huì)被解釋10次,顯然這是很浪費(fèi)性能。引入JIT后看一下v8引擎執(zhí)行js的過程Js 源代碼經(jīng)過詞法分析、語法分析、語義分析生成AST樹,再生成中間代碼,中間代碼進(jìn)入解釋器中執(zhí)行,同時(shí)分析器會(huì)監(jiān)控代碼的執(zhí)行情況,如果一段代碼被反復(fù)執(zhí)行,那么這個(gè)段代碼被標(biāo)記為熱點(diǎn)代碼,同時(shí)會(huì)把這段代碼送到編譯器中編譯,同時(shí)生成優(yōu)化后機(jī)器碼,等下次執(zhí)行到這段代碼,就可以直接運(yùn)行優(yōu)化后的代碼。但是也有特殊的情況,因?yàn)閖s是動(dòng)態(tài)語言,類型是不固定的,有可能上一秒這個(gè)段代碼被標(biāo)記為熱點(diǎn)代碼,下一秒該熱點(diǎn)代碼對(duì)應(yīng)的優(yōu)化代碼可能就被丟棄。感興趣的可以看一下?這篇文章[5]

          ASM.js

          所以為了解決類型問題?WebAssembly?前身?ASM.js?出現(xiàn),?ASM.js?是?Mozilla?在?2013?年推出的,?ASM.js?是一個(gè)?javascript?嚴(yán)格子集,?ASM.js?雖然可以手寫,但是一般都是使用編譯器將?C++/C?或者一些其他語言轉(zhuǎn)為?ASM.js?文件。生成的?ASM.js?文件變量都是靜態(tài)類型,不用在運(yùn)行時(shí)判斷變量類型,從而使得?js?引擎可以采用?AOT(Ahead Of Time)?的編譯策略,也就是在運(yùn)行前直接編譯成機(jī)器碼,因此運(yùn)行速度會(huì)有一定的提升。那為什么?ASM.js?并沒有流行起來,其一它還是沒有一個(gè)統(tǒng)一的標(biāo)準(zhǔn)。它只是一個(gè)由一個(gè)廠商推出的,非標(biāo)準(zhǔn)的 JavaScript 子集而已,而它的使用者根據(jù)自己的偏好和習(xí)慣來使用它。WebAssembly 則不同,它是由幾大主要的瀏覽器廠商共同設(shè)計(jì)的。其二無論?ASM.js?如何優(yōu)化,歸根結(jié)底還是一個(gè)js文件,看一下上面v8引擎執(zhí)行js的圖片,可以看出只要是js文件,就需要經(jīng)過解析,生成中間代碼,而這兩步是JavaScript代碼在引擎執(zhí)行過程當(dāng)中消耗時(shí)間最多的兩步。而WebAssembly不用經(jīng)過這兩步。這就是WebAssembly比asm.js更快的原因。

          Emscripten介紹

          Emscripten 是一個(gè)針對(duì)WebAssembly的開源編譯器,它可以將C和C++代碼或任何其他使用LLVM的語言編譯成WebAssembly,并在Web、Node.js或其他wasm運(yùn)行時(shí)運(yùn)行它。Emscripten 中包含倆個(gè)重要的工具鏈

          • emcc 是clang和gcc的臨時(shí)替代品,emcc使用LLVM和clang將c/c++編譯為WebAssembly

          • EmscriptenSDK用于安裝整個(gè)工具鏈,包括EMCC和LLVM等。EmscriptenSDK(Emsdk)可以在Linux、Windows或MacOS上使用。

          安裝

          #?Get?the?emsdk?repo
          git?clone?[https://github.com/emscripten-core/emsdk.git](https://github.com/emscripten-core/emsdk.git?"https://github.com/emscripten-core/emsdk.git")

          #?Enter?that?directory
          cd?emsdk

          #?Fetch?the?latest?version?of?the?emsdk?(not?needed?the?first?time?you?clone)
          git?pull

          #?Download?and?install?the?latest?SDK?tools.
          ./emsdk?install?latest

          #?Make?the?"latest"?SDK?"active"?for?the?current?user.?(writes?.emscripten?file)
          ./emsdk?activate?latest

          #?Activate?PATH?and?other?environment?variables?in?the?current?terminal
          source?./emsdk_env.sh

          通過以上操作,在當(dāng)前命令行運(yùn)行?emcc -v?,打印如下代表安裝成功

          emcc?-v

          emcc?(Emscripten?gcc/clang-like?replacement?+?linker?emulating?GNU?ld)?2.0.29?(28ca7fb7ce895b21013212e4644a5794a15a76f9)
          clang?version?14.0.0?([https://github.com/llvm/llvm-project](https://github.com/llvm/llvm-project?"https://github.com/llvm/llvm-project")?8e284be04f2cd43a821289133a759afa2844f935)
          Target:?wasm32-unknown-emscripten
          Thread?model:?posix
          InstalledDir:?/Users/bytedance/Desktop/emsdk/upstream/bin

          為了確保每次打開終端都可以使用emcc,還需要將如下代碼加入到?.bash_profile?或?.zsh

          source?emcc目錄/emsdk_env.sh?&>?/dev/null

          使用

          • 將?c/c++?編譯為?js
          //?test.cpp
          #include?

          using?namespace?std;

          int?main()
          {
          ????cout?<"Hello?World"?<endl;
          }

          運(yùn)行?emcc ./test.cpp?,同級(jí)目錄生成?a.out.js?和?a.out.wasm?文件,第二個(gè)是包含編譯代碼的WebAssembly文件,第一個(gè)是包含加載和執(zhí)行代碼的運(yùn)行時(shí)支持的JavaScript文件。然后可以使用?nodejs?運(yùn)行?js

          node?./a.out.js

          終端輸出?Hello World

          • Emscripten還可以生成用于測(cè)試嵌入式JavaScript的HTML。要生成HTML,請(qǐng)使用-o(輸出)命令并指定一個(gè)html文件作為目標(biāo)文件:
          emcc?test.cpp?-o?hello.html

          然后可以在瀏覽器中打開hello.html 不幸的是,一些瀏覽器(包括Chrome、Safari和Internet Explorer)不支持file://xhr請(qǐng)求,并且不能加載HTML所需的額外文件(如.wasm文件或下面提到的打包文件數(shù)據(jù))。對(duì)于這些瀏覽器,您需要使用本地Web服務(wù)器提供文件,然后打開?http://localhost:8000/hello.html[6]?). 本人在練習(xí)的時(shí)候使用的是?http-server?安裝

          npm?i?http-server?-g

          在工作目錄運(yùn)行

          #?-o?打開瀏覽器
          #?-p?指定端口
          http-server?./?-o?-p?8085?

          在瀏覽器中打開?8085?端口

          WebAssembly 會(huì)取代 Javascript嗎?

          我認(rèn)為不會(huì)。我認(rèn)為?WebAssembly?和?JavaScript?是相輔相成的,WebAssembly是被設(shè)計(jì)成JavaScript的一個(gè)完善、補(bǔ)充,而不是一個(gè)替代品。大家怎么認(rèn)為?

          參考鏈接

          Emscripten 官網(wǎng)[7]?c++項(xiàng)目轉(zhuǎn)成wasm全過程[8]?https://juejin.cn/post/6844903709806182413#heading-27[9]?https://juejin.cn/post/6844903469808091143[10]

          [1]

          WebAssembly入門-未來可能發(fā)生的巨變:?https://windliang.wang/2020/11/18/WebAssembly%E5%85%A5%E9%97%A8-%E6%9C%AA%E6%9D%A5%E5%8F%AF%E8%83%BD%E5%8F%91%E7%94%9F%E7%9A%84%E5%B7%A8%E5%8F%98/

          [2]

          例子:?http://www.ruanyifeng.com/blog/2018/01/assembly-language-primer.html

          [3]

          WebAssembly入門-未來可能發(fā)生的巨變:?https://windliang.wang/2020/11/18/WebAssembly%E5%85%A5%E9%97%A8-%E6%9C%AA%E6%9D%A5%E5%8F%AF%E8%83%BD%E5%8F%91%E7%94%9F%E7%9A%84%E5%B7%A8%E5%8F%98/

          [4]

          mdn定義:?https://developer.mozilla.org/zh-CN/docs/WebAssembly/Understanding_the_text_format

          [5]

          這篇文章:?https://juejin.cn/post/6844903469262831624

          [6]

          http://localhost:8000/hello.html:?http://localhost:8000/hello.html

          [7]

          Emscripten 官網(wǎng):?https://emscripten.org/index.html

          [8]

          c++項(xiàng)目轉(zhuǎn)成wasm全過程:?https://zhuanlan.zhihu.com/p/158586853

          [9]

          https://juejin.cn/post/6844903709806182413#heading-27:?https://juejin.cn/post/6844903709806182413#heading-27

          [10]

          https://juejin.cn/post/6844903469808091143:?https://juejin.cn/post/6844903469808091143



          往期推薦


          大廠面試過程復(fù)盤(微信/阿里/頭條,附答案篇)
          面試題:說說事件循環(huán)機(jī)制(滿分答案來了)
          專心工作只想搞錢的前端女程序員的2020

          最后


          • 歡迎加我微信,拉你進(jìn)技術(shù)群,長(zhǎng)期交流學(xué)習(xí)...

          • 歡迎關(guān)注「前端Q」,認(rèn)真學(xué)前端,做個(gè)專業(yè)的技術(shù)人...

          點(diǎn)個(gè)在看支持我吧
          瀏覽 102
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  毛片网些 | 欧美色图在线看 | 成人影音先锋AV免费电影 | 天天摸日日摸人人看 | 成人AV片导航 |