V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
seanwhy
V2EX  ›  程序员

基于 Webassembly 的一些问题

  •  2
     
  •   seanwhy · 47 天前 · 2675 次点击
    这是一个创建于 47 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近在迁移公司 C/S 架构程序( C++、三维软件),想往浏览器端迁移,目前正在施行的方案是用 emscripten 编译的 webassembly 模块。
    公司程序用了大量的三方库比如:gdal 、ffmpeg 、opengles ,三方库又依赖了大量其他的库,比如 gdal 依赖了 geos 、proj 、curl 、libtiff 、sqlite3 等。因此编译采用的是静态链接,即所有.a 最终生成的是一个.wasm 文件。
    我这里基本用了最新的版本,以防对 webassembly 缺乏支持。
    那么问题来了:
    问题 1:基于如此巨量的三方库以及自有实现代码,这个 wasm 文件会很巨大(百兆体量),浏览器能加载的出来吗,或者此种体量是否规范?
    问题 2:据说 webassembly 使用内存上限有限制,大概 4GB ,有方法能突破限制吗?我司程序就是个吃内存的家伙
    问题 3:如此多的三方库,是要一个个验证能否在浏览器上运行测试用例吗?还是说只要经过 emscripten 编译过,就基本认定在浏览器端运行基本没有问题?
    问题 4:性能衰减问题,大概是多少体量,自我感觉能效不高,怕迁移完毕卡成狗。
    第 1 条附言  ·  47 天前
    有层想表达的意思是:C++代码使用标准库、使用 pthread 、使用脱离系统 api 的方式,使用 wasm 内置文件系统,首先能正常运行在 windows 、linux 下,那么用 emsctipten 编译出来,是否就意味着无需验证,也能运行于浏览器?按照我的理解,一旦 C++内部编译成功,无关运行平台,运行结果也是能正常
    第 2 条附言  ·  46 天前
    我这里就是单纯用 C++技术,实现能在浏览器端运行起来的不带界面的三维图形程序,前端技术基本不考虑,这个交给前端二次开发人员调用我们提供的接口来实现。我们和前端唯一交互就是暴露的接口,键鼠我们已经内部抱走
    51 条回复    2024-03-29 16:36:31 +08:00
    morenacl
        1
    morenacl  
       47 天前
    这...图啥啊
    seanwhy
        2
    seanwhy  
    OP
       47 天前
    @morenacl 只能说客户端被浏览器蚕食的太厉害了
    duiying
        3
    duiying  
       47 天前
    搞个简单版本运营看看咯
    tool2d
        4
    tool2d  
       47 天前
    emscripten 对很多库支持并不好,比如 curl 就不太好编译。

    wasm 只适合中等偏小的软件,运行巨型商业软件够呛,代码估计要大改。
    seanwhy
        5
    seanwhy  
    OP
       47 天前
    @tool2d curl 我编出来.a 了,gdal 也编出来了,但之前公司用的 opengl ,要改 opengles ,因此目前还跑不起来,所以趁机问问。
    gam2046
        6
    gam2046  
       47 天前
    性能损耗应该是比较严重的,ffmpeg 是一个计算密集型的应用,wasm 版本的 ffmpeg 在转码方面,有时候只有 10%的速度。
    tool2d
        7
    tool2d  
       47 天前   ❤️ 1
    @seanwhy 那你比较厉害,正常来说 curl 用的是标准 socket ,这在 wasm 浏览器里,都是不被支持的。

    我以前遇到的最大问题,是内存管理方面。emscripten 粘合层,用了一种很奇怪的方法处理 fopen/fwrite ,文件大于 2 百兆就有问题,反正很折腾。
    nieyujiang
        8
    nieyujiang  
       47 天前   ❤️ 1
    4g 内存这个目前无解.我司的程序目前也是身受其害.
    w4ngzhen
        9
    w4ngzhen  
       47 天前
    “只能说客户端被浏览器蚕食的太厉害了” 还是没有 Get 到真正的原因,公司是希望以后这块的软件都通过浏览器作为媒介来使用,因为它随时可用,方便快捷,不用下客户端?但假设你真正编译为了 wasm ,大小并不比原生应用小。当然,我只是作为旁观者提出的疑问😂。
    johnhsm2333
        10
    johnhsm2333  
       47 天前
    我们这边做 Web 视频编辑器的,也是大量使用 wasm 场景,感觉这里问题提的挺好的。
    johnhsm2333
        11
    johnhsm2333  
       47 天前
    w4ngzhen
        12
    w4ngzhen  
       47 天前   ❤️ 1
    另外对于产品设计方面,看到贵司的软件是 C++三维软件,我假设是一款生产力软件,作为用户,我用客户端在 PC 上使用,明显比在浏览器上使用更加放心😂。
    johnhsm2333
        13
    johnhsm2333  
       47 天前
    @johnhsm2333 #11
    1. wasm 体积不能太大,会影响网页首屏时间,这个要压缩到 10 到 20m 左右,然后利用客户端缓存。所以不建议是所有功能都打包进来,只包括 js 或浏览器接口无法使用的功能会好一些。
    2.确实有
    3.验证挺麻烦的,我们也是限制了浏览器版本,比如 safari 无法访问,chrome 和 edge 特定版本以上之类的;
    4.项目劣化会挺明显,而且前端同学不懂 wasm 的话,很难优化,所以我们已经把很多功能都使用 js 实现一遍了,这样效果最好。
    icyalala
        14
    icyalala  
       47 天前
    对于通用计算来说,性能可以认为是降低到 1/3~1/5 ; simd/gpu 加速的部分性能下降就更多了,至少降一个量级。
    cat
        15
    cat  
       47 天前
    你司的三维软件是不是卖不出去??搞这幺蛾子
    horizon
        16
    horizon  
       47 天前
    你 wasm 打包压缩了吗,压缩完还 100 多 M ?
    mightybruce
        17
    mightybruce  
       47 天前
    https://mp.weixin.qq.com/s/1XmH55nqs7wavsWJNT-tSw
    B 站 有 ffmpeg 编译成 wasm 的案例, 并有相关 git 地址
    mightybruce
        18
    mightybruce  
       47 天前
    wasm 其实是非常有用的, 服务器计算挪动到客户端计算,大大减轻了服务端的压力和资源消耗。
    thinkershare
        19
    thinkershare  
       47 天前
    基本要大改,完全重写。
    seanwhy
        20
    seanwhy  
    OP
       47 天前
    @gam2046 那一般情况呢,
    @johnhsm2333 1.大小问题可以通过进度条规避,毕竟大型软件,对加载时间可以有一定的宽容; 4.软件设计基本无需外部前端参与,完全由内部 C++暴露接口供外部调用,前端只需要做界面美化和接口调用的事,可以理解为我们提供了一个二次开发的 sdk
    Beginner1
        21
    Beginner1  
       47 天前
    我司跟 3D 上 web 和他们一样,目前感觉也还好。不过我们主要使用 vtk ,代码确实进行了大量整改,就速度来说其实还好。可能我们功能没有他们那么复杂。当然 Ai 这些只有上云了。
    seanwhy
        22
    seanwhy  
    OP
       47 天前
    @cat 说白了浏览器端二次开发者多,客户端二次开发式微了
    seanwhy
        23
    seanwhy  
    OP
       47 天前
    @icyalala 这么严重么?看资料是原生的 1/3~2/3
    gam2046
        24
    gam2046  
       47 天前
    @seanwhy #20 一般情况下,纯计算能力,wasm 效率能到 native 的 50%都够呛。毕竟 wasm 还是一个虚拟机,还得交给浏览器解释执行。而且现阶段 wasm 对于 pthread 的支持还是有点磕磕绊绊,很多开源项目的 wasm ,我看他们的处理方式是直接改成单线程保平安。
    tool2d
        25
    tool2d  
       47 天前
    @seanwhy "那么用 emsctipten 编译出来,是否就意味着无需验证,也能运行于浏览器?"

    验证很简单,写个单元测试跑一下就行了。

    把对 wasm 的内心期望减半,再减半,就比较符合浏览器里运行的真实情况。
    kaiserzhang123
        26
    kaiserzhang123  
       47 天前
    内存 4GB 的原因是因为编译到 wasm32 位的操作,最大就支持 4gb 内存,想要突破就只能使用 wasm64 位
    kaiserzhang123
        27
    kaiserzhang123  
       47 天前
    @nieyujiang 编译到 wasm64 位就没有 4gb 内存的限制
    icyalala
        28
    icyalala  
       47 天前
    @seanwhy https://00f.net/2023/01/04/webassembly-benchmark-2023/ 这有个通用计算的测试接近你的资料,平均下降到 43%,但是这是最快的 wasm 实现的结果。实际浏览器可能会再慢一些。

    https://ffmpegwasm.netlify.app/docs/performance/ 这有个 Chrome+ffmpeg.wasm 的性能测试,平均下降到 8%,差了一个量级。
    guanzhangzhang
        29
    guanzhangzhang  
       47 天前
    大佬,xorg-x11-server 和 openresty 有静态编译姿势吗
    Jirajine
        30
    Jirajine  
       47 天前
    就算能跑,你觉得 serve 一个 100m 的 wasm 文件给浏览器合适吗?

    能编译到 wasm 的代码,可以认为就是可以运行的。但代码可以运行,不代表代码链接/调用的 API 也被支持。所以代码可以重用,其他都得重写。
    br_wang
        31
    br_wang  
       47 天前
    提到 wasm ,我也有个问题:一个使用了 wasm 的网页,如果被 iframe 嵌入到另一个网页,还能正常访问到 wasm 文件并顺利运行么?
    rabbbit
        32
    rabbbit  
       47 天前
    churchill
        33
    churchill  
       47 天前
    emscripten 文档上大量篇幅是讲 porting 和 optimizing webgl, 可见坑不少,祝楼主好运
    可能不是很恰当的例子,有些图形库说是支持 emscripten 编译,可是桌面上是调的 opengl4.6 ,用 emscripten 编译就使用 emscripten 自带的 gl 头文件了,如果你的 shader 不是针对 es 300 写的运行起来就挂了
    image72
        35
    image72  
       47 天前   ❤️ 1
    我觉得你想把这些搬到浏览器运行之前,可以先考虑发几个版本的 electron 编译版试试水,能移植的移植,能改写的改写,再考虑浏览器。electron 也是完整浏览器,也能支持内置 wasm 以及原生
    从底层原生一步跨到纯浏览器 wasm, 步子太大,容易扯到蛋
    opengg
        36
    opengg  
       47 天前 via Android
    成功的项目基本没有全程 wasm 的,线上大多数都是 web 界面加部分重逻辑重计算部分走 wasm 调用。
    当然也有类似的尝试,但我还没见过 full wasm 的商业产品。
    sunzhuo
        37
    sunzhuo  
       47 天前
    @br_wang 没问题
    sunzhuo
        38
    sunzhuo  
       47 天前
    我建议用 threejs 重现桌面版的 api ,然后再考虑 wasm 移植一些 c 功能。
    mahaoqu
        39
    mahaoqu  
       47 天前
    @gam2046 改单线程不用 Webworker 遇到计算密集型不会卡死 UI 么
    mahaoqu
        40
    mahaoqu  
       47 天前
    如果你引用的所有库都能直接源码级跨 Win/Linux 两个系统,那大概率直接用 emscripten 编译到 WebAssembly 是能用的。比如去年谷歌那边就说 SQLite 用浏览器的 OPFS 后端跑通了,但这样的库还是太少。
    seanwhy
        41
    seanwhy  
    OP
       46 天前
    @sunzhuo 已有 webgl 产品线,我们这个属于 C++原生线,得弄些突破成果
    seanwhy
        42
    seanwhy  
    OP
       46 天前
    @mahaoqu 好消息的三方库用的多,但方法用的又不多,纯属贪图其中某几个 API ,那感觉还有点戏
    seanwhy
        43
    seanwhy  
    OP
       46 天前
    @kaiserzhang123 大佬细说,编译时加上什么标识呢
    seanwhy
        44
    seanwhy  
    OP
       46 天前
    @guanzhangzhang 只要你的库有 configure 或者 cmake ,编出来应该不难啊
    seanwhy
        45
    seanwhy  
    OP
       46 天前
    @gam2046 多线程这块用的是 C++标准库,实际内部调用走的还是 pthread ,初步实验感觉没什么问题
    seanwhy
        46
    seanwhy  
    OP
       46 天前
    @churchill 已针对性剔除 OpenGL ,改用 OpenGLES 友好子集,应该问题不大
    jimrok
        47
    jimrok  
       46 天前
    感觉你要改设计,全部搬进 wasm 会崩溃的。建议 web 的版本先做简单的尝试,剥离最主要的功能,极简设计,看看效果。很多计算是不是可以用后端服务实现,这样不需要移植到浏览器上。
    seanwhy
        48
    seanwhy  
    OP
       46 天前
    @opengg Google earth 网页版?
    jeesk
        49
    jeesk  
       46 天前 via Android
    wasm 很多实现,有点扯,比如网络请求转移成 fetch , 太恶心了, 拿证书都拿不到,
    dode
        50
    dode  
       45 天前
    可以搞客户端,纯跑程序,客户端额外开一个 HTTP 服务,浏览器提供界面啊
    money1991
        51
    money1991  
       29 天前
    我司也是搞客户端办公软件的,我把上千万行 c++代码编译到 wasm 了,并且也跑起来了。这块你也可以参考下 photoshop 或 libreoffice 的 wasm 版本,代码量都是这个级别的。
    1. 先说体积,编译完大约 100M 左右,用 br 最高级压缩完 20M 左右,这个大小其实以目前网速不算大,配合缓存基本也仅影响首次。
    2. 首次初始化稍慢,出去下载的时间,chrome 还会把它编译到一个二进制缓存,后续启动会非常快。
    3. 性能我个人感觉能接受,但我司项目不依赖 opengl ,不算是强计算密集型项目,感觉应该有原生 50%左右的性能。
    目前项目没有在搞了。。。老板觉得可能时机还有点早,有点遗憾。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   876 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:32 · PVG 04:32 · LAX 13:32 · JFK 16:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.