成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Asm.js: Javascript的編譯目標(biāo)

用戶84 / 1028人閱讀

摘要:來(lái)自于應(yīng)用的一個(gè)新領(lǐng)域編譯成的應(yīng)用它是應(yīng)用的一個(gè)全新流派,由的項(xiàng)目催生而來(lái)。所有外部數(shù)據(jù)在一個(gè)稱為堆的對(duì)象中存儲(chǔ)并被引用。到目前為止,大部分的使用情況下,代碼性能是至關(guān)重要的比如運(yùn)行游戲,圖像,處理語(yǔ)言翻譯和庫(kù)。

正如許多開發(fā)者一樣,我也為Asm.js的前景而感到興奮不已。最近的新聞——Asm.js正在被Firefox支持——引起了我的興趣。同樣感興趣的還有Mozilla和Epic聲明(mirror)他們已經(jīng)為Asm.js而支持Unreal Engine 3——并且運(yùn)行十分良好。
獲得一個(gè)C++游戲引擎運(yùn)行Javascript,并使用WebGL來(lái)渲染,這是一個(gè)重大的突破,這個(gè)突破很大程度上歸功于Mozilla開發(fā)的工具鏈,才使得這一切變得可能。
由于Unreal Engine 3開始支持Asm.js,我瀏覽了來(lái)自Twitter,blogs和其他地方的回應(yīng),當(dāng)一部分開發(fā)者表現(xiàn)出對(duì)這項(xiàng)制造奇跡的技術(shù)躍躍欲試時(shí),我也看到許多疑惑:Asm.js是一個(gè)插件嗎?Asm.js能讓我平時(shí)使用的Javascript運(yùn)行的更快嗎?它兼容所有瀏覽器嗎?從這些回應(yīng)中,我認(rèn)為Asm.js及其相關(guān)技術(shù)很重要,我將解釋這些技術(shù),好讓開發(fā)者明白發(fā)生了什么以及他們將會(huì)如何從這些技術(shù)中獲益。另外,為了寫出這篇我對(duì)這項(xiàng)技術(shù)的概覽,我也請(qǐng)教了David Herman(Mozilla研究院的高級(jí)研究員)一大堆關(guān)于Asm.js和如何梳理這些知識(shí)的問(wèn)題。

什么是 Asm.js?

為了理解 Asm.js 及其適用與瀏覽器的所在,你需要知道它的由來(lái)以及它存在的意義。
Asm.js 來(lái)自于 JavaScript 應(yīng)用的一個(gè)新領(lǐng)域: 編譯成JavaScript的C/C++應(yīng)用. 它是 JavaScript 應(yīng)用的一個(gè)全新流派,由 Mozilla 的 Emscripten項(xiàng)目催生而來(lái)。
Emscripten 將 C/C++ 代碼傳入 LLVM, 并將 LLVM生成的字節(jié)碼轉(zhuǎn)換成 JavaScript (具體的, Asm.js, 是 JavaScript 的一個(gè)子集).

如果被編譯成的 Asm.js 的代碼做了一些渲染工作,那么它幾乎總是由WebGL來(lái)處理的 (并且由 OpenGL 來(lái)渲染). 這樣技術(shù)上就利用了JavaScript 和瀏覽器的好處,但幾乎完全避開了頁(yè)面中Javascript使用的實(shí)際的、常規(guī)的代碼執(zhí)行和渲染路徑.

Asm.js是Javascript的一個(gè)子集,它深度的限制了其所能做的范圍和所能操作的對(duì)象。這樣做才能使得Asm.js的代碼能夠盡可能運(yùn)行的快,從而盡可能減少各種假定情況的出現(xiàn),從而能夠把Asmjs代碼直接轉(zhuǎn)變成為匯編代碼。有一個(gè)特別值得注意的是 - Asmjs還只是Javascript - 不需要瀏覽器的插件或者是別的特性去運(yùn)行它(雖然一個(gè)能夠檢測(cè)出并且優(yōu)化Asmjs代碼的瀏覽器當(dāng)然是要快一些)。它是Javascript的一個(gè)特定的子集,為性能優(yōu)化而生,特別是為那些需要編譯成為Javascript的應(yīng)用程序來(lái)做優(yōu)化。
最佳的理解Asmjs工作的方式,就是看看一些Asmjs-編譯化的代碼。讓我們看看這個(gè)函數(shù),這是從真實(shí)的Asmjs編譯模塊里面提取出來(lái)的函數(shù)(來(lái)自BananaBread demo)。我對(duì)代碼格式做了調(diào)整,所以看起來(lái)更加合乎代碼片段的閱讀,原本它是一個(gè)高度壓縮的JavaScript代碼中的一個(gè)很大的計(jì)算機(jī)二進(jìn)制對(duì)象。

function Vb(d) {
    d = d | 0;
    var e = 0, f = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0,
        o = 0, p = 0, q = 0, r = 0, s = 0;
    e = i;
    i = i + 12 | 0;
    f = e | 0;
    h = d + 12 | 0;
    j = c[h >> 2] | 0;
    if ((j | 0) > 0) {
        c[h >> 2] = 0;
        k = 0
    } else {
        k = j
    }
    j = d + 24 | 0;
    if ((c[j >> 2] | 0) > 0) {
        c[j >> 2] = 0
    }
    l = d + 28 | 0;
    c[l >> 2] = 0;
    c[l + 4 >> 2] = 0;
    l = (c[1384465] | 0) + 3 | 0;
    do {
        if (l >>> 0 < 26) {
            if ((4980736 >>> (l >>> 0) & 1 | 0) == 0) {
                break
            }
            if ((c[1356579] | 0) > 0) {
                m = d + 4 | 0;
                n = 0;
                while (1) {
                    o = c[(c[1356577] | 0) + (n << 2) >> 2] | 0;
                    do {
                        if (a[o + 22 | 0] << 24 >> 24 == 24) {
                            if (!(Vp(d, o | 0) | 0)) {
                                break
                            }
                            p = (c[m >> 2] | 0) + (((c[h >> 2] | 0) - 1 | 0) * 40 & -1) + 12 | 0;
                            q = o + 28 | 0;
                            c[p >> 2] = c[q >> 2] | 0;
                            c[p + 4 >> 2] = c[q + 4 >> 2] | 0;
                            c[p + 8 >> 2] = c[q + 8 >> 2] | 0;
                            c[p + 12 >> 2] = c[q + 12 >> 2] | 0;
                            c[p + 16 >> 2] = c[q + 16 >> 2] | 0;
                            c[p + 20 >> 2] = c[q + 20 >> 2] | 0;
                            c[p + 24 >> 2] = c[q + 24 >> 2] | 0
                        }
                    } while (0);
                    o = n + 1 | 0;
                    if ((o | 0) < (c[1356579] | 0)) {
                        n = o
                    } else {
                        break
                    }
                }
                r = c[h >> 2] | 0
            } else {
                r = k
            } if ((r | 0) == 0) {
                i = e;
                return
            }
            n = c[j >> 2] | 0;
            if ((n | 0) >= 1) {
                i = e;
                return
            }
            m = f | 0;
            o = f + 4 | 0;
            q = f + 8 | 0;
            p = n;
            while (1) {
                g[m >> 2] = 0.0;
                g[o >> 2] = 0.0;
                g[q >> 2] = 0.0;
                Vq(d, p, f, 0, -1e3);
                n = c[j >> 2] | 0;
                if ((n | 0) < 1) {
                    p = n
                } else {
                    break
                }
            }
            i = e;
            return
        }
    } while (0);
    if ((c[1356579] | 0) <= 0) {
        i = e;
        return
    }
    f = d + 16 | 0;
    r = 0;
    while (1) {
        k = c[(c[1356577] | 0) + (r << 2) >> 2] | 0;
        do {
            if (a[k + 22 | 0] << 24 >> 24 == 30) {
                h = b[k + 14 >> 1] | 0;
                if ((h - 1 & 65535) > 1) {
                    break
                }
                l = c[j >> 2] | 0;
                p = (c[1384465] | 0) + 3 | 0;
                if (p >>> 0 < 26) {
                    s = (2293760 >>> (p >>> 0) & 1 | 0) != 0 ? 0 : -1e3
                } else {
                    s = -1e3
                } if (!(Vq(d, l, k | 0, h << 16 >> 16, s) | 0)) {
                    break
                }
                g[(c[f >> 2] | 0) + (l * 112 & -1) + 56 >> 2] = +(b[k + 12 >> 1] << 16 >> 16 | 0);
                h = (c[f >> 2] | 0) + (l * 112 & -1) + 60 | 0;
                l = k + 28 | 0;
                c[h >> 2] = c[l >> 2] | 0;
                c[h + 4 >> 2] = c[l + 4 >> 2] | 0;
                c[h + 8 >> 2] = c[l + 8 >> 2] | 0;
                c[h + 12 >> 2] = c[l + 12 >> 2] | 0;
                c[h + 16 >> 2] = c[l + 16 >> 2] | 0;
                c[h + 20 >> 2] = c[l + 20 >> 2] | 0;
                c[h + 24 >> 2] = c[l + 24 >> 2] | 0
            }
        } while (0);
        k = r + 1 | 0;
        if ((k | 0) < (c[1356579] | 0)) {
            r = k
        } else {
            break
        }
    }
    i = e;
    return
}

從技術(shù)上說(shuō),這是Javascript代碼,但是我們已經(jīng)看到這段代碼一點(diǎn)都不像大多我們正常看到的操作DOM的Javascript。通過(guò)看這段代碼,我們可以發(fā)現(xiàn)幾件事:

這段特定的代碼只能處理數(shù)值。事實(shí)上這是所有Asm.js代碼的情形。Asm.js只能處理被挑出的幾種不同的數(shù)值類型,而沒(méi)有提供其他的數(shù)據(jù)類型(包括字符串,布爾型和對(duì)象)。

所有外部數(shù)據(jù)在一個(gè)稱為堆的對(duì)象中存儲(chǔ)并被引用。堆在本質(zhì)上是一個(gè)大數(shù)組(應(yīng)當(dāng)是一個(gè)在性能上高度優(yōu)化的類型化數(shù)組)。所有的數(shù)據(jù)在這個(gè)數(shù)組中存儲(chǔ)——有效的替代了全局變量,結(jié)構(gòu)體,閉包和其他形式的數(shù)據(jù)存儲(chǔ)。

當(dāng)訪問(wèn)和賦值變量時(shí),結(jié)果被統(tǒng)一的強(qiáng)制轉(zhuǎn)換成一種特定類型。例如f = e | 0;給變量f賦值e,但它也確保了結(jié)果的類型是一個(gè)整數(shù)(|0把值轉(zhuǎn)換成整數(shù),確保了這點(diǎn))。這也發(fā)生在浮點(diǎn)型上——注意0.0和g[...] = +(...)的使用.

看看從數(shù)據(jù)結(jié)構(gòu)中寫入讀出的值,用c表示的數(shù)據(jù)結(jié)構(gòu)好像是一個(gè)Int32Array(存儲(chǔ)32位整數(shù),因?yàn)檫@些值總是通過(guò)|0被轉(zhuǎn)換成或者轉(zhuǎn)換自一個(gè)整數(shù)),g好像是一個(gè)Float32Array(存儲(chǔ)32位浮點(diǎn)數(shù),因?yàn)檫@些值總是通過(guò)包裹上+(...)轉(zhuǎn)換成浮點(diǎn)數(shù))。

這么做以后,結(jié)果就是高度優(yōu)化,并且可以直接從Asm.js語(yǔ)法轉(zhuǎn)換成匯編,而不必像常常要對(duì)Javascript做的那樣解釋它。它有效地削減了使像Javascript之類的的動(dòng)態(tài)語(yǔ)言緩慢的東西:例如需要垃圾收集器和動(dòng)態(tài)類型。

作為一個(gè)更容易理解的Asm.js代碼示例,我們來(lái)看看一個(gè)Asm.js規(guī)范上的例子:

function DiagModule(stdlib, foreign, heap) {
    "use asm";

    // Variable Declarations
    var sqrt = stdlib.Math.sqrt;

    // Function Declarations
    function square(x) {
        x = +x;
        return +(x*x);
    }

    function diag(x, y) {
        x = +x;
        y = +y;
        return +sqrt(square(x) + square(y));
    }

    return { diag: diag };
}

看看這個(gè)模塊,它完全能讓人理解!閱讀這些代碼,我們能更好的理解Asm.js模塊的結(jié)構(gòu)。一個(gè)模塊包含在一個(gè)函數(shù)中,它以頂部的"use asm";指令開始。它提示解釋器這個(gè)函數(shù)里所有的東西可以被當(dāng)成Asm.js處理,并可以直接被編譯成匯編代碼。
注意在函數(shù)頂部的三個(gè)參數(shù):stdlib,foreigh和heap。stdlib對(duì)象包含了很多內(nèi)建數(shù)學(xué)函數(shù)的引用。foreign提供了自定義用戶功能(例如在WebGL中繪制圖形)的訪問(wèn)。最后,heap給了你一個(gè)ArrayBuffer,它可以通過(guò)很多透鏡(例如Int32Array和Float32Array)來(lái)觀察。

該模塊剩下的被分成了三部分:變量聲明,函數(shù)聲明,還有最后把函數(shù)導(dǎo)出暴露給用戶的一個(gè)對(duì)象。
導(dǎo)出是尤其要去理解的一個(gè)重點(diǎn),因?yàn)樗茸屗心K中的代碼被當(dāng)成Asm.js處理,又使得代碼可以被其他普通的Javascript代碼使用。因此,在理論上你可以通過(guò)使用上面的DiagModule代碼,寫下如下代碼:

document.body.onclick = function() {
    function DiagModule(stdlib){"use asm"; ... return { ... };}

    var diag = DiagModule({ Math: Math }).diag;
    alert(diag(10, 100));
};

這帶來(lái)了一個(gè)Asm.js模塊DiagModule,它被Javascript解釋器特殊處理,但仍然能夠被其他Javascript代碼使用(我們?nèi)阅茉L問(wèn)并使用它,比如一個(gè)單擊事件處理程序)。

性能如何?

現(xiàn)在Asm.js唯一的實(shí)現(xiàn)就是 nightly versions of Firefox(而且也只是針對(duì)特定的幾個(gè)平臺(tái))。原來(lái)的數(shù)字告訴我們Ams.js的性能是非常非常不錯(cuò)的。對(duì)于復(fù)雜的應(yīng)用(比如上面的游戲)性能僅僅比普通C++編譯的慢兩倍(可以和Java或者C#相媲美)。實(shí)際上,這已經(jīng)比目前瀏覽器的運(yùn)行時(shí)環(huán)境要快很多了,幾乎是最新版的Firefox或者Chrome執(zhí)行速度的4~10倍。

基于目前最好測(cè)試,可以看出Asm.js在性能上有很大的提升??紤]到現(xiàn)在僅僅是Asm.js的最初開發(fā)階段,相信在不久的將來(lái)就會(huì)有更大的性能提升。
看到Asm.js和當(dāng)前的Firefox和Chrome引擎的性能差距是很有意思的。一個(gè)4~10倍的性能差異是非常巨大的(就好像拿這些瀏覽器和IE6做性能對(duì)比一樣)。有趣的是雖然有這么大的性能差異,但是許多的Asm.js演示例子仍然是可以在Chrome和Firefox——這些代表著當(dāng)前Javascript先進(jìn)技術(shù)的引擎——上使用的。這也就是說(shuō)他們的性能明顯不如一個(gè)運(yùn)行著優(yōu)化過(guò)的Asm.js代碼的瀏覽器相提并論。

使用情況

需要說(shuō)明的是現(xiàn)在幾乎所有基于Asm.js的應(yīng)用都是C/C++應(yīng)用使用Emscripten編譯的??梢钥隙ǖ恼f(shuō),在不久的將來(lái),這類即將運(yùn)行在Asm.js的應(yīng)用,將會(huì)從可以在瀏覽器中運(yùn)行這一可移植性中獲益,但是在支持javascript方面有一定復(fù)雜度的應(yīng)用將不可行。
到目前為止,大部分的使用情況下,代碼性能是至關(guān)重要的:比如運(yùn)行游戲,圖像,處理語(yǔ)言翻譯和庫(kù)。從一個(gè)關(guān)于Emscripten項(xiàng)目列表的概覽可以看到許多即將被廣大開發(fā)者使用的技術(shù)。

許多游戲引擎已經(jīng)被支持。一個(gè)好的演示也許就是BananaBread FPS游戲(源代碼),它可以直接在瀏覽器中運(yùn)行,支持多玩家和機(jī)器人。

支持javascript的LaTeX,即textlive.js,使用Emscripten,允許你完全在你的瀏覽器中編輯PDF文檔。

支持javascript的SQLite,能夠在Node.js中運(yùn)行。

NaCL:一個(gè)網(wǎng)絡(luò)加密解密的庫(kù)。

Asm.js支持

就像之前提到的那樣,現(xiàn)在只有nightly版本的Firefox支持Asm.js的優(yōu)化。
但是,要注意Asm.js格式的Javascript代碼仍然是Javascript,雖然其存在一些限制。這樣,其他的瀏覽器即使不支持Asm.js仍可以將其作為普通的Javascript代碼運(yùn)行。
有關(guān)代碼性能重要而令人不解的一點(diǎn)是:如果瀏覽器不支持typed array或者不能對(duì)Asm.js代碼進(jìn)行特殊的編譯,Asm.js的性能會(huì)變的很差。當(dāng)然,這并不止針對(duì)Asm.js,如果沒(méi)有這些特性,瀏覽器的性能在其他方面也會(huì)收到影響。

Asm.js與Web開發(fā)

你可能已經(jīng)看出來(lái)了,上面的Asm.js代碼不是手工輸入的的。Asm.js需要一些特殊的工具來(lái)編寫,而且其開發(fā)和編寫普通的Javascript代碼有很大區(qū)別。目前一般的Asm.js應(yīng)用都是從C/C++編譯到Javascript的,很顯然它們都不會(huì)與DOM進(jìn)行任何交互,而是直接與WebGL打交道。
為了能讓一般的開發(fā)者使用,需要一些更能讓人接受的中間語(yǔ)言。目前LLJS已經(jīng)逐漸實(shí)現(xiàn)向Asm.js編譯了。需要注意的是,LLJS這樣的語(yǔ)言同樣與常規(guī)的Javascript有很大區(qū)別,會(huì)讓許多Javascript開發(fā)者感到困擾。即使是用LLJS這樣更加友好的語(yǔ)言,編寫Asm.js必須要對(duì)復(fù)雜的代碼進(jìn)行優(yōu)化,這恐怕只有資深開發(fā)者能夠勝任了。
就算有了LLJS或者別的語(yǔ)言來(lái)幫助我們編寫Asm.js,我們也沒(méi)有同樣性能優(yōu)異的DOM可以使用。理想的環(huán)境應(yīng)該是將LLJS與DOM一起編譯產(chǎn)生單一的可執(zhí)行二進(jìn)制文件。我還想不出這樣做性能會(huì)有多好,但是我想這么做!

與David Herman的問(wèn)答

我寫信給David Herman(Mozilla Research的高級(jí)研究員),向他詢問(wèn)了一些問(wèn)題。他們是如何將Asm.js的各部分結(jié)合在一起的?他們又希望用戶從中得到什么呢?他親切地深入回答了這些問(wèn)題,有些回復(fù)很有趣。我希望你們也同樣能從中獲得啟發(fā)。

Asm.js的目標(biāo)是什么?你們這個(gè)計(jì)劃的目標(biāo)人群是哪些?

  

我們的目標(biāo)是讓開放網(wǎng)絡(luò)成為一個(gè)虛擬主機(jī),使之變?yōu)槠渌Z(yǔ)言和平臺(tái)的編譯目標(biāo)平臺(tái)。在最初的版本中,我們集中于編譯較底層的語(yǔ)言:C和C++。我們的長(zhǎng)期目標(biāo)是為更高層的語(yǔ)言提供支持,例如結(jié)構(gòu)對(duì)象和垃圾回收等特性。我們最終會(huì)讓其支持諸如JVM和.NET之類的應(yīng)用。

  

既然asm.js的確擴(kuò)展了web的基礎(chǔ),潛在的用戶群很廣。其中一批用戶就是那些想得到盡可能多的運(yùn)算能力的游戲開發(fā)者。除此之外,有開創(chuàng)性的web開發(fā)者總會(huì)用一切工具來(lái)完成目標(biāo),誰(shuí)能料到他們的辦法呢?所以我真心希望asm.js成為讓我想不到的創(chuàng)新應(yīng)用得以實(shí)現(xiàn)的技術(shù)。

創(chuàng)建一個(gè)利于用戶訪問(wèn)版本的Asm.js是否合理呢,比如一個(gè)更新版本的LLJS?或者是擴(kuò)展目前項(xiàng)目的范圍,而不僅僅是一個(gè)編譯器的目標(biāo)語(yǔ)言?

  

絕對(duì)可能。事實(shí)上,我的同事James Long最近聲明,他已經(jīng)從LLJS上開辟了一個(gè)初級(jí)的分支,用來(lái)編譯成為asm.js。在Mozilla 研究所的團(tuán)隊(duì)也試圖和James的工作相配合,從而能夠正式的讓LLJS支持asm.js。

  

我看法是,一般來(lái)說(shuō)你想手工書寫asm.js代碼的場(chǎng)景非常的少,和任何匯編語(yǔ)言一樣。更多的是,你想用具有豐富表達(dá)力的語(yǔ)言,而最終把它們高效編譯為 asm.js。當(dāng)然,當(dāng)一種語(yǔ)言達(dá)到極致的表達(dá)力,例如javascript,你就會(huì)難以預(yù)測(cè)其性能。(我的朋友 Slava Egorov寫一篇相當(dāng)好的文章來(lái)描述用高級(jí)語(yǔ)言寫高性能代碼的挑戰(zhàn)。LLJS的目標(biāo)是作為一種中間地帶,就像一種相對(duì)于asm.js匯編語(yǔ)言的C語(yǔ)言, 這樣就比寫原始的asm.js語(yǔ)言更加容易,而比常規(guī)的js有更可預(yù)知的性能。但是不象C,它仍然和常規(guī)的JS有著良好的互通。這樣,你可以用JS來(lái)寫你 的app的大部分,而對(duì)于那些高度消耗性能的地方,則可以專注用LLJS來(lái)完成。

有一個(gè)討論是關(guān)于,在目前支持Asm.js的瀏覽器和不支持的瀏覽器之間,會(huì)出現(xiàn)一種因此更新而形成的性能的分界,類似與2008/2009年中所發(fā)生的JavaScript性能競(jìng)爭(zhēng)。雖然技術(shù)上來(lái)看,Asm.js的代碼在現(xiàn)實(shí)中,可以運(yùn)行于任意兩者之上,而性能的不同,對(duì)于大多數(shù)的場(chǎng)合而言將會(huì)有有明顯的不同(譯者注:原詞是too crippling,意思大致是嚴(yán)重的傷害)。那么對(duì)于這種分界,以及高度限制Javascript,為什么你選擇了Javascript作為編譯的目標(biāo)?為什么不是另一種取代javascript的語(yǔ)言或者是一種插件?(譯者注:作者似乎是想說(shuō)明,Javascript的限制對(duì)于所有瀏覽器都會(huì)有影響,那么對(duì)于不支持Asm.js的瀏覽器會(huì)有所傷害,所以為什么不選擇別的語(yǔ)言或者是插件,這樣就會(huì)只影響自己的產(chǎn)品)

  

首先,我不認(rèn)為這種分界如你所定義的那么嚴(yán)重:我們做過(guò)一些出色的演示代碼的編譯工作,這些代碼在目前的瀏覽器上工作的很好,而且可以得益于asm.js這樣的性能“殺手”。

  

這 一點(diǎn)是當(dāng)然的事實(shí),你可以創(chuàng)建一個(gè)應(yīng)用程序,依賴于asm.js所曾益的性能,而且是可用的。與此同時(shí),就如同任何新的web平臺(tái)的能力,應(yīng)用程序可以決 定是否降低一些性能,減輕那些與計(jì)算密切相關(guān)的行為。對(duì)于一個(gè)應(yīng)用在降低性能的時(shí)候工作,和一個(gè)應(yīng)用完全不能工作是有些不同的。

  

更廣泛的來(lái)看,記得在00年之后開始的瀏覽器性能的競(jìng)爭(zhēng)對(duì)于今天的web有著顯著的好處,并且應(yīng)用伴隨著瀏覽器得到了改善。我相信同樣的事情會(huì)而且將發(fā)生在asmjs上。

拿Asm.js和Google的Native Client做比較,你覺(jué)得如何?他們似乎都有這類似的目標(biāo),同時(shí)Asmjs有著可以運(yùn)行在任何支持javascript的地方的優(yōu)勢(shì)。有過(guò)對(duì)于兩者之間的任何性能比較么?

  

嗯,Native Client有點(diǎn)不同,由於它其中配備了平臺(tái)相關(guān)的匯編代碼;我不認(rèn)為Google會(huì)作為一種web內(nèi)容技術(shù)而支持它(相對(duì)於是它用於Chrome Web Store 內(nèi)容或者 Chrome 擴(kuò)展而言),或者說(shuō),最近沒(méi)有。

  

便攜的Native Client (PNaCI)有著類似的目標(biāo),使用平臺(tái)無(wú)關(guān)的LLVM的bitcode來(lái)代替原始的匯編代碼。如你所說(shuō),asmjs的第一個(gè)優(yōu)勢(shì)就是其和現(xiàn)有的瀏覽器兼 容。我們也不必去創(chuàng)建一個(gè)系統(tǒng)的接口和重復(fù)全部的Web API中所有的接口層,好像Pepper API那樣,由於asmjs訪問(wèn)目前存在的API是通過(guò)直接使用Javascript的。最終,這將對(duì)於實(shí)現(xiàn)更加輕松有利:Luke Wagner在一個(gè)多月中,就把我們第一次實(shí)現(xiàn)的OdinMoney的實(shí)現(xiàn)版本移植到了Firefox,主要是靠他一個(gè)人的工作。因?yàn)閍smjs沒(méi)有一大堆的系統(tǒng)調(diào)用和API,而且因?yàn)樗窃贘avascript語(yǔ)法的基礎(chǔ)上建立起來(lái)的,你可以重復(fù)使用現(xiàn)存的Javascript的引擎和web運(yùn)行環(huán)境提供的全部機(jī)制。

  

我們本可以做一些和PNaCI的性能比較,不過(guò)這會(huì)有一定的工作量,而且我們更多的是專註於縮小和原始的native代碼性能的距離。我們計(jì)劃建立一些自動(dòng)化的性能測(cè)試,這樣就可以用圖表來(lái)描述相對(duì)於native C/C++編譯器,我們目前的進(jìn)展。

Emscripten是另一個(gè)Mozilla項(xiàng)目,也是Asm.js的主要兼容代碼的貢獻(xiàn)者。有多少Asm.js的開發(fā)被Emscripten的項(xiàng)目需求所支配?Emscripten又從引擎的提升上獲得了什么益處?

  

我們使用Emscripten作為Asm.js的第一個(gè)測(cè)試用例,通過(guò)這種途徑來(lái)保證它能夠正確適應(yīng)實(shí)際本地應(yīng)用的需求。當(dāng)然Emscripten受益也使他們想要支持的所有擁有本地應(yīng)用的人受益,比如Epic Games,我們僅在幾天之內(nèi)就與之組建了開發(fā)團(tuán)隊(duì),通過(guò)使用Emscripten和Asm.js來(lái)支持web版的Unreal Engine 3的開發(fā)。

  

但是Asm.js能夠使那些專注于底層javascript子集的任何人獲益。舉個(gè)例子,我們提到過(guò)的開發(fā)與Emscripten有相似功能的Mandreel編譯器的folks,我們相信他們可以從Asm.js中受益,就像不久前啟動(dòng)的Emscripten項(xiàng)目一樣。

  

Alon Zakai正在編譯我們的基準(zhǔn)測(cè)試程序,這個(gè)程序只比本地代碼要慢大約2倍,以前我們看到的數(shù)字是5倍到10倍或者20倍。這只是我們最初的OdinMonkey版本,這個(gè)版本的asm.js支持Mozilla的SpiderMonkey javascript引擎。在接下來(lái)的幾個(gè)月中,我希望看到更多的提升。

Asm.js的功能還會(huì)變動(dòng)么?隨著越來(lái)越多編譯器開發(fā)者的加入,你贊不贊同加入更多的附加功能(比如更高級(jí)的數(shù)據(jù)結(jié)構(gòu))?

  

當(dāng)然。Luke Wagner在Mozilla wiki上寫了asm.js與 OdinMonkey路線圖,里面討論了我們未來(lái)的計(jì)劃——我必須指出這里面沒(méi)有什么已經(jīng)確定了的但的確說(shuō)出了我們正在努力的方向。我很愿意加入對(duì)ES6結(jié)構(gòu)對(duì)象的支持。這將會(huì)提供垃圾回收機(jī)制與良好的類結(jié)構(gòu),幫助像JSIL這類編譯器將C#和Java編譯為Javascript。我們也希望加入ES7數(shù)值類型,這將提供32位浮點(diǎn)數(shù)和64位整數(shù)支持,也許還會(huì)為提供SIMD支持加入定長(zhǎng)向量。

可以做出JavaScript-to-Asm.js轉(zhuǎn)譯器么,它會(huì)被做出來(lái)么?

  

可以做出來(lái),但會(huì)做么?不一定。想想盜夢(mèng)空間中你每次進(jìn)行夢(mèng)中夢(mèng)的情景,時(shí)間將會(huì)變得多慢?一樣的道理,你要是想在JS中運(yùn)行一個(gè)JS引擎那一定會(huì)非常慢的。我們不嚴(yán)格地算一算,如果asm.js比原生代碼慢一倍,那在asm.js中運(yùn)行一個(gè)JS引擎,這引擎將會(huì)比它正常的速度慢一倍。

  

當(dāng)然,你總是可以在一個(gè)JS引擎中運(yùn)行另一JS引擎,誰(shuí)知道到底會(huì)怎樣呢?現(xiàn)實(shí)中的性能從來(lái)就不像理論計(jì)算那樣明確。我歡迎一些積極的hacker去嘗試它。事實(shí)上,斯坦福的學(xué)生Alex Tatiyants已經(jīng)用Emscripten將Mozilla的SpiderMonkey引擎編譯為JS了——你所需做的只是設(shè)置Emscripten編譯器參數(shù)讓它產(chǎn)生asm.js代碼,時(shí)間比我充裕的家伙可以嘗試一下……

現(xiàn)在Asm.js還不能進(jìn)行與有關(guān)DOM和瀏覽器的操作。創(chuàng)建一個(gè)Emscripten到Ams.js版本的DOM(就像DOM.js)如何?

  

這是一個(gè)漂亮的想法。這對(duì)目前剛剛起步的asm.js有點(diǎn)難度,現(xiàn)在我們還不支持任何DOM對(duì)象。在我們不斷為asm.js添加ES6類型的對(duì)象時(shí),這種想法有可能變得可行而并且更加有效。

  

這方面一個(gè)比較酷的應(yīng)用可能就是看看到底web平臺(tái)能多有效的執(zhí)行自承載業(yè)務(wù)。創(chuàng)建DOM.js一個(gè)動(dòng)機(jī)就是想要看一下純JS實(shí)現(xiàn)的DOM能否擊敗傳統(tǒng)、低效的出入隊(duì)列式的、跨堆棧的JS堆與相關(guān)C++ DOM對(duì)象之間的內(nèi)存管理方法。有了asm.js的支持,DOM.js也許可以在性能上勝過(guò)那些高度優(yōu)化過(guò)的數(shù)據(jù)結(jié)構(gòu)。這值得一試。

編寫Asm.js代碼與編寫一般的Javascript代碼相比確實(shí)十分困難,你有什么工具可以提供給開發(fā)者和編譯器作者呢?

  

首先最重要的是,我們有LLJS這樣的語(yǔ)言。就像你提到的那樣,可以將其編譯為Asm.js。同樣,我們?cè)趯⑵涫褂糜趙eb時(shí)也會(huì)有一些挑戰(zhàn),例如使用source maps之類的技術(shù)將生成的代碼對(duì)應(yīng)到瀏覽器開發(fā)者工具中的原始代碼。我很高興看到source maps的發(fā)展,它已經(jīng)可以反饋更加豐富的調(diào)試信息。我們要在在source maps的極小尋址信息和格式復(fù)雜的調(diào)試信息(DWARF)之間進(jìn)行取舍,這是一個(gè)代價(jià)平衡的問(wèn)題。

  

對(duì)asm.js而言,我認(rèn)為近期我們將會(huì)將精力集中在LLJS上,同時(shí)我也一直歡迎開發(fā)者告訴我們一些能夠改善他們編程體驗(yàn)的建議。

我覺(jué)得你們很樂(lè)于和其他瀏覽器廠商一起工作,你們的合作和討論進(jìn)展如何?

  

沒(méi)錯(cuò)。我們之間有過(guò)一些非正式的討論,他們一直對(duì)我們給予鼓勵(lì),我相信我們能做的更好。我很樂(lè)觀,我們可以與很多廠商一起發(fā)展asm.js,那時(shí)它可以讓我們輕松地在不改變架構(gòu)的情況下開發(fā)應(yīng)用。就像我說(shuō)的,事實(shí)上Luke只用了幾個(gè)月就開發(fā)出了OdinMonkey,這很令人激動(dòng)。我很高興收到V8引擎下asm.js的bug報(bào)告。

  

更重要的是,我希望開發(fā)者可以檢查asm.js的源碼,看看我們是怎么想的,并反饋給我們和其他瀏覽器廠商。

原文:Asm.js: The JavaScript Compile Target
轉(zhuǎn)載自:開源中國(guó) - DrZ, 看天吃飯, tnjin, magiclogy, LeoXu

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/87468.html

相關(guān)文章

  • WebAssembly 為什么比 asm.js 快?

    摘要:并且于年月日,四個(gè)主要的瀏覽器一致同意宣布的版本已經(jīng)完成,即將推出一個(gè)瀏覽器可以搭載的穩(wěn)定版本。因此本文著重介紹為什么比更快。本文主要表達(dá)的是為什么應(yīng)該是更快的。則不同,它是由幾大主要的瀏覽器廠商共同設(shè)計(jì)的。 作者:Alon Zakai 編譯:胡子大哈 翻譯原文:http://huziketang.com/blog/posts/detail?postId=58ce80d2a6d8a0...

    Binguner 評(píng)論0 收藏0
  • 前端每周清單半年盤點(diǎn)之 WebAssembly 篇

    摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。利用降低三倍加載速度自推出之后,很多開發(fā)者都開始嘗試在小型項(xiàng)目中實(shí)踐,不過(guò)尚缺大型真實(shí)案例比較。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目...

    Alan 評(píng)論0 收藏0
  • Asm.js簡(jiǎn)單介紹

    摘要:的代碼采用另外一套編譯器,將代碼預(yù)先編譯成機(jī)器指令,在編譯過(guò)程或運(yùn)行過(guò)程中,一旦發(fā)現(xiàn)語(yǔ)法錯(cuò)誤或違反類型標(biāo)記的情況出現(xiàn),便重新將代碼交予引擎解析執(zhí)行。 Asm.js簡(jiǎn)介 早前流行的JavaScript將會(huì)統(tǒng)治世界這個(gè)梗,很好的說(shuō)明了JavaScript的將來(lái),能用JavaScript書寫的都會(huì)用JavaScript來(lái)進(jìn)行書寫,不過(guò)JavaScript的弱類型是其被黑性能的很大不一部分,而...

    lijy91 評(píng)論0 收藏0
  • 圖說(shuō) WebAssembly(六):現(xiàn)狀與展望

    摘要:現(xiàn)狀年月日,主流的四大瀏覽器達(dá)成了共識(shí)并宣布的最小可行產(chǎn)品已經(jīng)完成。更快的函數(shù)調(diào)用當(dāng)前,在中調(diào)用函數(shù)比想象的要慢。直接操作目前,沒(méi)有任何方式能夠操作。這就導(dǎo)致了部分應(yīng)用可能會(huì)因此而推遲發(fā)布時(shí)間。結(jié)束現(xiàn)如今已經(jīng)相當(dāng)快速。 本文是圖說(shuō) WebAssembly 系列文章的最后一篇。如果您還未閱讀之前的文章,建議您從第一篇入手。 現(xiàn)狀 2017 年 2 月 28 日,主流的四大瀏覽器達(dá)成了共識(shí)...

    clasnake 評(píng)論0 收藏0
  • Emscripten教程之代碼可移植性與限制(一)

    摘要:教程之代碼可移植性與限制一翻譯云荒杯傾本文是專欄系列文章之一,更多文章請(qǐng)查看專欄。下面是正文代碼可移植性與限制幾乎可以編譯任何可移植的代碼到。如果標(biāo)準(zhǔn)機(jī)構(gòu)將共享狀態(tài)添加到中,支持多線程代碼將成為可能。 Emscripten教程之代碼可移植性與限制(一) 翻譯:云荒杯傾本文是Emscripten-WebAssembly專欄系列文章之一,更多文章請(qǐng)查看專欄。也可以去作者的博客閱讀文章。歡迎...

    yangrd 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<