国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Emscripten教程之代碼可移植性與限制(一)

yangrd / 2208人閱讀

摘要:教程之代碼可移植性與限制一翻譯云荒杯傾本文是專欄系列文章之一,更多文章請查看專欄。下面是正文代碼可移植性與限制幾乎可以編譯任何可移植的代碼到。如果標準機構(gòu)將共享狀態(tài)添加到中,支持多線程代碼將成為可能。

Emscripten教程之代碼可移植性與限制(一)

翻譯:云荒杯傾
本文是Emscripten-WebAssembly專欄系列文章之一,更多文章請查看專欄。
也可以去作者的博客閱讀文章。
歡迎加入Wasm和emscripten技術(shù)交流群,群聊號碼:939206522。

Emscripten代碼移植主題涵蓋了將C、C++代碼移植到Emscripten時需要考慮的所有核心考慮問題,以及一般的編碼和調(diào)試指南。
共有以下主題。

代碼可移植性與限制、emscripten的運行環(huán)境、連接C++與JavaScript、文件和文件系統(tǒng)、多媒體數(shù)據(jù)和圖形、調(diào)試、多線程編程支持、移植SIMD代碼、Asyncify、Emterpreter

每一部分內(nèi)容都比較多,本文主要講第一部分,代碼可移植性與限制。下面是正文:

代碼可移植性與限制

Emscripten幾乎可以編譯任何可移植的c/c++代碼到JavaScript。但由于瀏覽器環(huán)境限制和Emscripten編譯出來的代碼的限制,一些代碼為了能被編譯需要做改動,本文就幫我們找出這部分代碼。

1、關(guān)于可移植性的指導

本節(jié)解釋了哪些類型的代碼是不可移植的(或者更難于移植);哪些代碼可以編譯,但會運行得很慢。開發(fā)人員可以使用這些信息來評估移植代碼和重寫代碼的工作量。

1.1 不能編譯的代碼

為了使Emscripten工作,下面類型的代碼需要重寫。(理論上,在使用模擬的情況下,可以使用Emscripten解決這些問題,但速度非常慢。)

代碼是多線程的,并使用共享狀態(tài)。JavaScript有線程(web workers),但它們不能共享狀態(tài)。它們傳遞消息postMessage()。

Note:
如果JavaScript標準機構(gòu)將共享狀態(tài)添加到webworker中,支持多線程代碼將成為可能。

代碼依賴于大端序架構(gòu)。Emscripten編譯的代碼目前需要一個little-endian主機運行,這種主機占了連接到互聯(lián)網(wǎng)的99%的機器。這是因為JavaScript類型化數(shù)組服從主機字節(jié)序,LLVM需要知道目標字節(jié)序是什么。

依賴于x86對齊方式的代碼。x86允許未對齊的內(nèi)存讀寫(例如,您可以從一個非偶數(shù)地址讀取一個16位的值),但是其他的架構(gòu)不是。對于emscripten生成的JavaScript,其內(nèi)存對齊方式是未定義的。如果您使用

SAFE_HEAP = 1構(gòu)建您的代碼,那么您將得到一個清晰的運行時異常,參見調(diào)試。

使用本機環(huán)境的底層特性的代碼,例如setjmp / longjmp涉及的本地堆棧操作。(we support proper setjmp/longjmp, i.e.,

jumping down the stack, but not jumping up to an unwound stack, which is undefined behavior).

掃描寄存器或堆棧的代碼。因為在寄存器或堆棧上的變量可能是被放置到一個并不能被掃描的js局部變量里保存的。

NOTE:
如果你是一個喜歡自己寫垃圾回收程序的程序員,可能對這類代碼比較熟。。。

具有特定于體系結(jié)構(gòu)的內(nèi)聯(lián)匯編(比如包含x86代碼的asm())的代碼是不可移植的。這段代碼需要用可移植的C或C++來替換。有時,代碼庫會將可移植的代碼和可選的內(nèi)聯(lián)程序集寫在一起作為優(yōu)化,你需要找到一個選項使內(nèi)聯(lián)匯編代碼不可用。

1.2 能編譯但是運行得比較慢的代碼
Note:
當你要優(yōu)化代碼的時候,就會知道了解這些事項是有用的。

下面類型的代碼會被編譯,但是可能運行的很慢:

64位整型變量。數(shù)學運算(+,-,*,/)是慢的,因為它們是被模擬的。這是因為JavaScript沒有本地64位int類型,因此這是不可避免的。

C++異常。在JavaScript中,這些代碼通常會使JavaScript引擎關(guān)閉各種優(yōu)化。因此,在- o1和上面的默認情況下,異常會被關(guān)閉。要重新啟用它們,請運行emcc與- s DISABLE_EXCEPTION_CATCHING= 0。

setjmp also prevents relooping around it,迫使我們使用一種效率較低的方法來模擬控制流。

2、API限制

瀏覽器環(huán)境和JavaScript不同于C/C++通常運行的本地環(huán)境。這些差異對如何調(diào)用和使用本地API施加了一些限制。本部分列出了一些比較明顯的限制。

2.1 網(wǎng)絡

Emscripten支持libc庫的網(wǎng)絡函數(shù),但您必須限制他們是異步(非阻塞)操作。這是因為底層的JavaScript網(wǎng)絡函數(shù)是異步的。

2.2 文件系統(tǒng)

Emscripten支持libc文件系統(tǒng)函數(shù),C /C++代碼可以以正常方式編寫。

在瀏覽器環(huán)境中運行的代碼是沙盒sandboxed,并且不直接訪問本地文件系統(tǒng)。然后,Emscripten就創(chuàng)建了一個虛擬文件系統(tǒng),它可以預裝數(shù)據(jù),或者鏈接到url來懶加載。這會影響同步文件系統(tǒng)函數(shù)調(diào)用以及一個項目如何被編譯。關(guān)于這方面,請參見文件系統(tǒng)概述。

2.3 主函數(shù)死循環(huán)

瀏覽器事件模型使用合作模式的多任務處理——每個事件都有一個運行的“turn”,然后必須將控制權(quán)返回給瀏覽器事件循環(huán),這樣其他事件就可以處理了。
HTML頁面掛起的一個常見原因是JavaScript未完成并且未將控制權(quán)返回給瀏覽器。

這將影響含有死循環(huán)的主函數(shù)的代碼編寫。有關(guān)更多信息,請參見Emscripten Runtime環(huán)境。

3、函數(shù)指針的問題

函數(shù)指針有三個主要的問題:
1、指針類型轉(zhuǎn)換會引起指針調(diào)用失敗。

針對函數(shù)聲明時的簽名不同,函數(shù)指針會被存儲到不同的表中。當一個函數(shù)被調(diào)用時,它會在與當前函數(shù)指針簽名關(guān)聯(lián)的表中搜索它。如果你進行了指針類型轉(zhuǎn)換,而指針和所有的表并沒有被修改,則調(diào)用代碼將在錯誤的表中查找。而錯誤的表中實際上很可能并沒有一個叫該名字的指針,這樣就出錯了。

例如,一個聲明為int(int)(返回int,接收int)的函數(shù),會被添加到表FUNCTION_TABLE_ii。如果您將一個指向該函數(shù)指針投射到void(int)(不返回,接收int),那么代碼將在FUNCTION_TABLE_vi中查找函數(shù)。

你可能看到編譯警告:

warning: implicit declaration of function

推薦的解決方案是重構(gòu)代碼以避免這種情況,如下面的Asm指針轉(zhuǎn)換所描述的那樣。

2、當你使用-o2以及更高優(yōu)化級別的時候,比較不同類型的函數(shù)指針會產(chǎn)生錯誤的結(jié)果,而錯誤的函數(shù)指針可能更具誤導性。要檢查你的代碼出問題的原因,可以將aliasing_function_pointer設為零,(- s aliasing_function_pointer= 0)進行編譯。

NOTE:
在asm.js中,函數(shù)指針存儲在特定函數(shù)類型的表中。如FUNCTION_TABLE_ii。

在較低級別的優(yōu)化中,每個函數(shù)指針在所有函數(shù)類型表上都有一個惟一的索引值(一個函數(shù)指針只在其中一個表的某個索引位置存在,在所有其他表中
這個索引位置都是一個空槽)。因此,比較函數(shù)指針(索引)能給出了一個準確的結(jié)果,但如果是試圖在錯誤的表中調(diào)用函數(shù)指針,將會拋出一個錯誤,因為該索引是空的。

在-o2和更高級別的優(yōu)化設置下,表被優(yōu)化,以至于所有函數(shù)指針都在順序索引中。這是一個有用的優(yōu)化,因為如果沒有所有空槽,表就更緊湊,
但它確實意味著函數(shù)索引不再是“全局”的惟一(因為一個函數(shù)指針在這張表中的索引位置與在另一張表中的索引位置不同了)。此時需要一張?zhí)囟ǖ谋?和在這樣表中的特定位置索引才能夠唯一索引到一個函數(shù)。

因此,高級別的優(yōu)化編譯:
1、由于不同類型的函數(shù)可以有相同的索引(盡管在不同的表中),函數(shù)指針的比較可能會產(chǎn)生錯誤的結(jié)果。
2、函數(shù)指針代碼中的錯誤更難于調(diào)試,因為它們導致錯誤的代碼被調(diào)用,而不是顯式的錯誤(就像在表中的“漏洞”中那樣)。

3、結(jié)構(gòu)體按值傳遞時,老版本的clang會為c和c++代碼生成兩種不同的代碼,這兩種格式的代碼不兼容,你可能會收到一個警告。
解決方案是按引用傳遞結(jié)構(gòu)體,或者不要在有結(jié)構(gòu)體的位置混淆c和c++(比如,重命名.c為.cpp)。

Asm指針轉(zhuǎn)換

如上所述,在asm.js模式下,函數(shù)指針必須使用正確的類型調(diào)用,否則調(diào)用將失敗。這是因為在函數(shù)聲明的時候,每個函數(shù)指針會基于這個函數(shù)的簽名被存儲在一個特定的表中: 將指針轉(zhuǎn)換為另一個類型會導致調(diào)用代碼在錯誤的位置(表)查找函數(shù)指針。

NOTE:
對于每種類型的函數(shù)指針都有一個多帶帶的表,可以讓JavaScript引擎知道每個函數(shù)指針調(diào)用的確切類型,這樣也好進而優(yōu)化他們。

有三種解決辦法,優(yōu)先選擇第二種:

調(diào)用者在函數(shù)指針被調(diào)用之前把指針類型再轉(zhuǎn)回原來的指針類型,這是有問題的因為這需要調(diào)用者知道它原來的類型是什么,而調(diào)用者實際上并不知道一個指針之前的類型是什么。

創(chuàng)建一個不需要轉(zhuǎn)換的適配器函數(shù),從適配器函數(shù)調(diào)用原始函數(shù)。

使用EMULATE_FUNCTION_POINTER_CASTS。當你使用-s EMULATE_FUNCTION_POINTER_CASTS=1編譯時,Emscripten將發(fā)出代碼來模擬運行時的函數(shù)指針類型轉(zhuǎn)換,

添加額外的參數(shù)/刪除參數(shù)/更改參數(shù)類型/添加或刪除返回類型等。這可以增加顯著的運行時開銷,因此不推薦,但值得嘗試。

4、特定瀏覽器限制

本頁面列出了一些 與Emscripten編譯出來的應用程序和游戲相關(guān)的 主要瀏覽器的最新版本之間的差異:

函數(shù)emscripten_get_now()以毫秒的形式返回一個wallclock time。

Opera 12.16和Windows谷歌Chrome 28.0.1500.95有一個限制,即計時器的精度僅為毫秒。
在其他主流瀏覽器上(IE10,firefox22,非windows的Chrome 28),也都是亞毫秒精度。

WebGL并沒有在Internet Explorer得到完全支持(至少在IE12之前)。

Opera 12.16對W3C的File API的支持有限。特別是它不支持createObjectURL函數(shù),

這意味著不可能使用瀏覽器的圖像編解碼器來解碼Emscripten虛擬文件系統(tǒng)中的預加載文件。

Emscripten中OpenAL和SDL audio的支持依賴于Web Audio API。

Emscripten代碼移植系列文章

Emscripten代碼移植主題系列文章是emscripten中文站點的一部分內(nèi)容。
第一個主題介紹代碼可移植性與限制
第二個主題介紹Emscripten的運行時環(huán)境
第三個主題第一篇文章介紹連接C++和JavaScript
第三個主題第二篇文章介紹embind
第四個主題介紹文件和文件系統(tǒng)
第六個主題介紹Emscripten如何調(diào)試代碼

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/91865.html

相關(guān)文章

  • Emscripten教程優(yōu)化你的代碼

    摘要:優(yōu)化項也會引發(fā)一些問題。檢查你的代碼是否工作并修復問題。從起,及以上的優(yōu)化級別默認啟動了這項設置。目前正在進行改進。代碼移植系列文章代碼移植主題系列文章是中文站點的一部分內(nèi)容。 作者:云荒杯傾歡迎加入Wasm和emscripten技術(shù)交流群,群聊號碼:939206522。 這是關(guān)于Emscripten的系列文章,更多文章請看下面鏈接。 Emscripten代碼移植系列文章 Emscr...

    Jokcy 評論0 收藏0
  • Emscripten教程優(yōu)化你的代碼

    摘要:優(yōu)化項也會引發(fā)一些問題。檢查你的代碼是否工作并修復問題。從起,及以上的優(yōu)化級別默認啟動了這項設置。目前正在進行改進。代碼移植系列文章代碼移植主題系列文章是中文站點的一部分內(nèi)容。 作者:云荒杯傾歡迎加入Wasm和emscripten技術(shù)交流群,群聊號碼:939206522。 這是關(guān)于Emscripten的系列文章,更多文章請看下面鏈接。 Emscripten代碼移植系列文章 Emscr...

    bladefury 評論0 收藏0
  • Emscripten教程Emscripten的運行時環(huán)境(二)

    摘要:運行時環(huán)境與大多數(shù)應用程序所期望的環(huán)境不同。不過程序是要手動交換緩沖區(qū)的。第一個主題介紹代碼可移植性與限制第二個主題介紹的運行時環(huán)境第三個主題第一篇文章介紹連接和第三個主題第二篇文章介紹第四個主題介紹文件和文件系統(tǒng)第六個主題介紹如何調(diào)試代碼 翻譯:云荒杯傾本文是Emscripten-WebAssembly專欄系列文章之一,更多文章請查看專欄。也可以去作者的博客閱讀文章。 Emscrip...

    VishKozus 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<