最近鼓捣的一个项目,移植了个浏览器版的 scrypt 算法:
https://github.com/EtherDream/WebScrypt由于 scrypt 对性能要求很高,所以做了各种优化。
先是用 emscripten 编译成 asm.js ,不过速度还是不够理想,比 native 慢太多了。
于是用浏览器的 profiles 找出最 heavy 的代码,发现 blockmix 和 salsa8 函数消耗了一大半计算,重点优化。
这里用了最笨的办法,在 C 代码上把循环和数组都手动展开,比如 int X[16] 的数组拆成 int X0, X1 ..., X15(其实完全可以用 clang 实现,不过暂时没找到选项,反正手动也很简单)。
这么一折腾 Chrome 上性能提升近 2 倍!
最后优化体积,毕竟 emscripten 编译出来的 js 有上万行。于是写了个小脚本( src/mod_asmjs/c-bind/reduce.js ),把最核心的逻辑提取出来,包括内存初始化数据。
这样体积从大几百 K 降到小几十 K 。
还有就是 scrypt 支持并发维度(参数 P ),所以这里用 Worker 来实现。如果 P > 1 ,这个脚本可甩现有的 js 版 scrypt 好多倍- -
另外为了提升体验,加了进度回调和终止的功能。不过加上这个之后,性能下降了 10% 左右。
因为原先的计算过程是完整的,现在被切分成了好几块,中间有些调度开销。(终止功能 没有用 Worker 的 terminate 方法,因为那样 Worker 就废了,下次用还得重新创建。所以是在小块任务调度时停止的)
大家看看还有什么地方可以优化的,可以讨论下~
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
https://tanronggui.xyz/t/343887
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.