色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

什么是wasm組件?使用Rust開發wasm組件實戰

OSC開源社區 ? 來源:凹凸實驗室 ? 2023-09-22 11:30 ? 次閱讀

什么是wasm組件?

wasm 全稱 WebAssembly,是通過虛擬機的方式,可以在服務端、客戶端如瀏覽器等環境執行的二進制程序。它有速度快、效率高、可移植的特點。

對我們 Web 前端工程最大的好處就是可以在瀏覽器端使用二進制程序處理一些計算量大的處理,使用他比 javascript 快的特點優化性能。

目前瀏覽器對wasm的兼容性如下:

cd675886-5871-11ee-939d-92fbcf53809c.jpghttps://img10.360buyimg.com/imagetools/jfs/t1/180904/35/36038/170761/64ded9bdF6f54c383/e85e037cdd4fa1fd.jpg

在移動端除了 android 4.4 和 ios 10 下不支持外,其他版本都能提供支持。還需要注意的是 wasm 有可能占用大量內存,使用第三方包含 wasm 調用的組件需要注意內存占用防止閃退。

為什么用Rust?

wasm模塊 可以用多種語言來編譯,包括 C/C++/C#、Rust、JAVA、Go。在這里使用 Rust 是因為他有嚴格的內存管理機制,從語法上盡量避免內存溢出,讓工程師寫出更安全的程序。

而且還有配套的工具 wasm-pack,讓使用 Rust 編寫的代碼,編譯包裝成 npm 包,讓使用這段程序的其他代碼可以像使用其他公共庫一樣調用,不需要額外學習成本。

工具安裝

安裝 rustup,它是 Rust 安裝器和版本管理工具。對于 web 前端來說相當于 nvm 這樣的工具。按照 Rust 官網的方法安裝:https://www.rust-lang.org/zh-CN/tools/install同時也會安裝 cargo,它是 Rust 的構建工具和包管理器。對于 web 前端來說相當于 npm 這樣的工具。

安裝 wasm-pack,他是上文提到的把 Rust 程序編譯包裝成 wasm 組件的工具。同樣按照 wasm-pack 官網的方法安裝:https://rustwasm.github.io/wasm-pack/installer/

使用 wasm 模板使用 wasm-pack 提供的模板可以快速生成 Rust 的 wasm 項目。

cargogenerate--githttps://github.com/rustwasm/wasm-pack-template

輸入希望的項目目錄名稱,將新建目錄并在其中生成項目。

在目錄下我們可以看到幾個文件,其中一個是 Cargo.toml ,這個是 Rust 項目的描述文件,對于 web 前端來說相當于 package.json 文件。

項目目錄下還有一個 src 目錄,里面有 lib.rs 和 utils.rs 兩個文件,其中 lib.rs 這個文件就是我們主要的邏輯入口,他引用了 wasm-bindgen 庫來輸出暴露給外部調用的接口,在函數之前加上#[wasm_bindgen]可以讓外部調用這個方法。

編譯項目

本來 Rust 的項目編譯用的是 cargo build 的命令,但是我們這里是希望編譯 wasm 組件,所以用的是 wasm-pack build 命令。

執行后會在項目目錄下的 pkg 目錄下生成編譯后的產品,是一個 npm 包的結構。需要調用這個組件的邏輯只需要像其他公共包一樣 import 就可以使用了。

實戰

以上的就是 wasm-pack 官方的教程,還有其他組件測試、發布等的流程先不在這里介紹了。以下用一個實際開發中的模塊來說一下開發 wasm 組件過程中遇到的問題和解決方法。

背景—

需要使用的 wasm 組件是一個優化3D模型的方法,傳入一個模型的頂點信息和距離閾值,比較每個頂點位置之間的距離,如果沒達到閾值距離就合并這兩個頂點,以達到減少頂點的優化目的。

原邏輯是使用 javascript 編寫的,在模型頂點數量比較多的時候執行的時間比較長。這種大量計算的情況就很適合使用 wasm 來處理。

數據傳遞—

頂點信息是存儲在一個 Float32Array 的數組中的,而 wasm 設計上除了 int 和 float 類型(對應 javascript 就是 number 類型)可以直接傳遞外,其他的類型都通過地址來傳遞。這對我們的程序來說是好消息,因為頂點信息的數據非常多,如果以值傳遞,就需要做數據復制,這個過程消耗的時間可能比我們換成 wasm 處理減少的時間還要多。得益這個特點,我們的入參可以直接傳入。

/*---rust----*/

//rust獲取javasctipt數據
pubfnadd_attribute(&mutself,attribute:&Float32Array,item_size:u32){
self.attributes.push(BufferAttribute{
array:attribute.to_vec(),
item_size,
});
}
/*---javascript----*/

//javascript傳遞數據到rust
for(constnameofattributeNames){
constattr=attrArrays[name]
bg.add_attribute(attr.array,attr.itemSize)
}

而計算后的結果,wasm 也提供了返回數組的指針和數組長度的方法,javascript 可以讀取 wasm 的內存空間,根據這兩個值構造新的頂點信息Float32Array。

/*---rust----*/

//返回指定數據的內存指針位置
pubfnget_attribute_ptr(&self,index:usize)->*constf32{
self.attributes[index].array.as_ptr()
}

//返回指定數據的長度
pubfnget_attribute_length(&self,index:usize)->usize{
self.attributes[index].array.len()
}
/*---javascript----*/

//javascript或取rust內存空間中的指定部分,構建Float32Array
constptr=bg.get_attribute_ptr(i)
constlength=bg.get_attribute_length(i)

constbuffer=newattr.array.constructor(wasm.getMemory().buffer,ptr,length)

數據類型—

合并頂點計算的邏輯中,有一段是這樣的:每個頂點的位置、UV等信息,經過給定的精度計算后,生成一個特征值,之后比較每個頂點的特征值,如果是相同的話就表示這兩個頂點可以合并。

原 javascript 版本的代碼是逐個信息按順序,加上分隔號,拼成一個字符串。

Rust 版本的代碼如果也按同樣的方法處理,因為頂點的信息量是不定的,有可能只有位置信息,也有可能有UV、法線、顏色等信息,所以生成的特征值字符串長度也不確定。

Rust 對於可變長度的字符串使用 String 類型,每次對字符串使用push_str方法增加內容。得到的結果 wasm 版本的執行速度跟 javascript 版本相差不大,甚至在某些情況下耗時還更多,經過逐個過程作排查,發現是在生成特征值和在表中查詢特征值這個過程中花費的時間比較多。

根據程序的意圖,特征值并不一定要是字符串,只需要在不同輸入值的時候能夠輸出相關的值就可以,這跟生成 hash 值的需求是一樣的,于是考慮將特征值生成替換成 hash 值計算。

因為在存儲特征值的表使用了std::hash_map類型,于是 hash 值也使用了其下的std::DefaultHasher類來計算

usestd::DefaultHasher;

...

letmuthasher=DefaultHasher::new();

forjin0..self.attributes.len(){
...

letvalue=(attr.array[i*attr.item_sizeasusize+indexasusize]
*self.shift_multiplier)
.trunc()asi32;

hasher.write_i32(value);

...
}

lethash=hasher.finish();

需要注意的是對寫入不同類型的內容,需要調用不同的方法,頂點信息中的值是正負值都用,經過精度計算后取整得到的值類型是i32,所以用write_i32來寫入內容。

生成的 hash 值為u64,作為hash_map的key記錄對應頂點的序號。

替換特征值的類型之后,wasm 版本的耗時達到了 javascript 版本的 1/2,基本符合 wasm 設計的性能范圍。

適配打包工具—

wasm-pack 工具打包出來的 npm 包,可以直接在webpack下加載并調用運行。

我們原本的項目使用 vite 構建,vite 對import wasm 組件策略和 webpack 的不一樣,vite 加載會返回一個加載方法,調用加載方法會返回一個 Promise,resolve 后才會返回跟 webpack 加載一樣的 wasm 組件。

我們要對 wasm-pack 生成的產物作一些修改,假設我們的 wasm 組件命名為 merge_vertice_wasm,生成的主 js 文件應該會命名為merge_vertice_wasm.js,內容如下:

import*aswasmfrom'./merge_vertice_wasm_bg.wasm'
import{__wbg_set_wasm}aswasm_bgfrom'./merge_vertice_wasm_bg.js'
__wbg_set_wasm(wasm);
export*from'./merge_vertice_wasm_bg.js'

為兼容 vite 的加載策略,修改成下面的內容

import*aswasmfrom'./merge_vertice_wasm_bg.wasm'
import*aswasm_bgfrom'./merge_vertice_wasm_bg.js'

letmemory
if(wasm.default){
wasm.default({
'./merge_vertice_wasm_bg.js':wasm_bg,
}).then(_wasm=>{
memory=_wasm.memory
wasm_bg.__wbg_set_wasm(_wasm)
})
}else{
memory=_wasm.memory
wasm_bg.__wbg_set_wasm(wasm)
}
export*from'./merge_vertice_wasm_bg.js'

exportfunctiongetMemory(){
returnmemory
}

就可以在 webpack 和 vite 下都可以順利加載并運行了。

其中增加了getMemory的方法供外部獲取 wasm 組件的內存空間。

wasm 調用 javascript 方法—

當我們在調試和測試性能表現時,需要打印日志,由于我們的 wasm 跑在瀏覽器環境中,我們需要調用 javascript 的方法,比如console.log和console.time。

wasm-bindgen 庫提供了 web-sys 的組件,讓 Rust 可以調用這些方法。

首先需要在cargo.toml中添加 web-sys 的依賴,并聲明需要用到的特性:

[dependencies]
wasm-bindgen="0.2.84"

[dependencies.web-sys]
version="0.3.64"
features=["console"]

這樣在下次編譯的時候,cargo 就會自動處理這些依賴,將會下載并構建。

然后在我們的 Rust 文件中,加入對 web-sys 的引用:

externcrateweb_sys;

就可以調用 javascript 的 console 下的方法了:

//調用console.log
web_sys::log_1(&JsValue::from(logContent));

//調用console.time(label)
web_sys::time_with_label(label);

//調用console.timeEnd(label)
web_sys::time_end_with_label(label);

原 javascript 版本優化模型耗時:

cd788f3e-5871-11ee-939d-92fbcf53809c.jpg

https://img14.360buyimg.com/imagetools/jfs/t1/109410/21/37527/8537/64dedd1cFe4c8c5c4/596fc2d36cc9fe5c.jpg

wasm 版本優化模型耗時:

cd87b464-5871-11ee-939d-92fbcf53809c.jpg

https://img12.360buyimg.com/imagetools/jfs/t1/188745/32/36809/10529/64dedd1cF49a8b5cc/8dea820d278ad577.jpg

總結

以上為根據官網文檔把模型合并頂點優化方法遷移為 wasm 版本的開發經歷,從安裝工具到發布、調試的整個過程。

中間因為對 Rust 數據類型的不熟悉和對不同前端構建工具對 wasm 組件處理的不同不夠清晰,在開發過程中遇到的問題和解決方法。

Rust 版本的代碼邏輯基本上是從 javascript 版本翻譯過來的,其中應該還有在 Rust 環境下的優化手段,將在之后的學習中繼續迭代。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Web
    Web
    +關注

    關注

    2

    文章

    1269

    瀏覽量

    69623
  • C++
    C++
    +關注

    關注

    22

    文章

    2114

    瀏覽量

    73792
  • Rust
    +關注

    關注

    1

    文章

    230

    瀏覽量

    6641

原文標題:給Web前端工程師看的用Rust開發wasm組件實戰

文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    從WasmEdge運行環境讀寫Rust Wasm應用的時序數據

    WebAssembly (Wasm) 正在成為一個廣受歡迎的編譯目標,幫助開發者構建可遷移平臺的應用。最近 Greptime 和 WasmEdge 協作,支持了在 WasmEdge 平臺上的 Wasm 應用通過 MySQL 協議
    的頭像 發表于 12-22 11:03 ?1028次閱讀

    鴻蒙實戰開發:【FaultLoggerd組件】講解

    Faultloggerd部件是OpenHarmony中C/C++運行時崩潰臨時日志的生成及管理模塊。面向基于 Rust 開發的部件,Faultloggerd 提供了Rust Panic故障日志生成能力。系統
    的頭像 發表于 03-12 16:22 ?1115次閱讀
    鴻蒙<b class='flag-5'>實戰</b><b class='flag-5'>開發</b>:【FaultLoggerd<b class='flag-5'>組件</b>】講解

    【RISC-V 生態軟件系列】Waft基礎教程三:模擬器的使用

    隆重宣布,waft應用現在可以脫離設備,運行在pc端上的模擬器了。waft應用開發又提效了,開發者可以在pc模擬器上調試好應用開發,頁面調試,然后在真機上運行。下面介紹模擬器的使用。準備工作確保
    發表于 03-08 09:36

    Wasm軟件生態系統安全分析

    ,致?于宣傳、實施、推?Wasm與OpenHarmony的集成,在OpenHarmony終端設備上可以安全高效的運行第三方開發者用 C、C++、Rust 等語言編寫的 Wasm 程序,
    發表于 09-05 15:29

    微信小程序如何開發?微信小程序教程視頻常用組件API開發項目實戰

    本文檔的主要內容介紹的是微信小程序如何開發?微信小程序教程視頻微信小程序入門與實戰 常用組件API開發技巧項目實戰詳細的介紹了
    發表于 08-28 14:41 ?88次下載

    迅雷鏈正式推出了WASM虛擬機模塊的源代碼和代碼庫

    隨著區塊鏈應用對虛擬機以及智能合約的需求增多,區塊鏈虛擬機技術也在逐漸完善。目前,基于WASM的虛擬機在速度和性能方面都有了顯著提升,且支持C、C++等多種編程語言,開發門檻更低。為了讓區塊鏈應用開發更便捷,迅雷鏈推出了雙虛擬機
    發表于 08-15 11:42 ?4455次閱讀
    迅雷鏈正式推出了<b class='flag-5'>WASM</b>虛擬機模塊的源代碼和代碼庫

    如何使用Rust進行Wasm合約開發

    Ontology Wasm 自從上線測試網以來,得到了社區開發人員的極大關注。因為這項技術使得業務邏輯復雜的 dApp 合約上鏈成本降低,極大豐富 dApp 生態。
    發表于 08-22 11:09 ?5295次閱讀

    如何使用C++進行Ontology Wasm合約開發

    Ontology Wasm 自從上線測試網以來便受到了社區開發人員的極大關注。Ontology Wasm 的上線將使得業務邏輯復雜的 dApp 合約上鏈成本降低,極大豐富 dApp 生態。在進行 Ontology
    發表于 08-29 17:30 ?911次閱讀

    重大性能更新:Wasm 后端將利用 SIMD指令和 XNNPACK多線程

    3 月,我們為 TensorFlow.js 推出了一個新的 WebAssembly(Wasm) 加速后端(繼續閱讀以進一步了解 Wasm 及其重要性)。今天,我們很高興宣布一項重大性能更新:自
    的頭像 發表于 09-30 15:15 ?9787次閱讀
    重大性能更新:<b class='flag-5'>Wasm</b> 后端將利用 SIMD指令和 XNNPACK多線程

    vim.wasm Vim-WebAssembly編譯器

    ./oschina_soft/vim.wasm.zip
    發表于 06-22 09:57 ?6次下載
    vim.<b class='flag-5'>wasm</b> Vim-WebAssembly編譯器

    Wasm container 如何運行服務WordPress的php.wasm鏡像

    該構建使用 WASI-SDK 工具集。它包括一個可以構建到 wasm32-wasi 目標的 clang 編譯器,以及在 WASI 之上實現基本 POSIX 系統調用接口的 wasi-libc。
    發表于 01-05 10:58 ?960次閱讀

    淺析Wasm-bpf架起Webassembly和eBPF內核可編程的橋梁

    Wasm 最初是以瀏覽器安全沙盒為目的開發的,發展到目前為止,WebAssembly 已經成為一個用于云原生軟件組件的高性能、跨平臺和多語言軟件沙箱環境
    的頭像 發表于 02-13 11:40 ?847次閱讀

    在WebAssembly中使用Rust編寫eBPF程序并發布OCI鏡像

    WebAssembly(Wasm)最初是以瀏覽器安全沙盒為目的開發的,發展到目前為止,WebAssembly 已經成為一個用于云原生軟件組件的高性能、跨平臺和多語言軟件沙箱環境,Wasm
    的頭像 發表于 02-14 18:10 ?1161次閱讀

    鴻蒙實戰開發學習【FaultLoggerd組件

    Faultloggerd部件是OpenHarmony中C/C++運行時崩潰臨時日志的生成及管理模塊。面向基于 Rust 開發的部件,Faultloggerd 提供了Rust Panic故障日志生成能力。系統
    的頭像 發表于 03-17 20:39 ?562次閱讀
    鴻蒙<b class='flag-5'>實戰</b><b class='flag-5'>開發</b>學習【FaultLoggerd<b class='flag-5'>組件</b>】

    OpenHarmony實戰開發-如何實現組件動畫。

    ArkUI為組件提供了通用的屬性動畫和轉場動畫能力的同時,還為一些組件提供了默認的動畫效果。例如,List的滑動動效,Button的點擊動效,是組件自帶的默認動畫效果。在組件默認動畫效
    的頭像 發表于 04-28 15:49 ?659次閱讀
    OpenHarmony<b class='flag-5'>實戰</b><b class='flag-5'>開發</b>-如何實現<b class='flag-5'>組件</b>動畫。
    主站蜘蛛池模板: 国产品无码一区二区三区在线 | 小777论坛 | 中文字幕一区二区三区在线观看 | 亚洲乱码在线卡一卡二卡新区 | 蜜柚在线观看免费高清官网视频 | 幻女FREE性俄罗斯学生 | 在线看片福利无码网址 | 无码AV动漫精品一区二区免费 | AV午夜午夜快憣免费观看 | 久久综合给会久久狠狠狠 | 久久久精品3d动漫一区二区三区 | 妈妈的职业3完整版在线播放 | 久久精品国产视频澳门 | 无码AV熟妇素人内射V在线 | 国产精品爽爽久久久久久蜜桃网站 | 三八成人网 | 99九九免费热在线精品 | a级毛片高清免费视频 | 国产成A人片在线观看 | 国产精品-区区久久久狼 | 久久精品国产只有精品 | 日本午夜精品理论片A级APP发布 | 波多结衣一区二区三区 | 国产精品97久久AV麻豆 | 亚洲精品国偷拍自产在线观看蜜臀 | 国产成人精品免费视频大全可播放的 | 亚洲黄色三级视频 | 被公疯狂玩弄的漂亮人妻 | 青柠在线观看免费高清电视剧荣耀 | 欧美日韩亚洲第一区在线 | 国产精品卡1卡2卡三卡四 | 麻豆久久国产亚洲精品超碰热 | 九九热在线视频精品店 | 十分钟在线观看免费视频高清WWW | 国产成人免费a在线资源 | 麻豆天美国产一区在线播放 | 精品成人片深夜 | 亚久久伊人精品青青草原2020 | 日韩性xxx| 一一本之道高清视频在线观看中文字幕 | 日本真人啪啪试看30秒 |