提到PNG,大多数人都不会感到陌生。
这种位图格式在图像领域使用频率仅次于 JPEG。
然而在 " 解码 PNG" 这件事上,23 年来主流的工具是一个叫做libpng的标准库。
但最近,一款号称 " 世界上最快的 PNG 图像解码器 " 诞生了,速度是 " 老大哥 " 的 1.22-2.75 倍!
除了速度方面的优势之外,更重要的一点,极其安全。
最快的 PNG 图像解码器
与用 C 语言为底层的 libpng 不同,这款 PNG 图像解码器采用的是Wuffs。
Wuffs 是一种内存安全的编程语言 ( 也是用这种语言编写的标准库 ) ,用于安全处理不受信任的文件格式。
包括解析、解码和编码图像,音频,视频,字体等。
Wuffs 不是一种通用编程语言。它是用来编写库的,完整的程序需要将 Wuffs 与另一种编程语言结合使用。
尤其是需要同时考虑性能和安全性的时候。
ps. 机智的你发现了吗,Wuffs 其实就是 Wrangling Untrusted File Formats Safely 的缩写。
不过它以前叫 Puffs,至于为什么将 Puffs ( parsing ) 改为 Wuffs ( wrangling ) ,留给你们自己去想象~
那么,解码速度快至 2.75 倍,怎么做到的?
Wuffs 通过 SIMD 加速方案,8 字节宽的输入和复制,一次将整个图像进行位扭曲和 zlib 解压缩到一个大的中间缓冲区来实现高性能。此法替代了此前的一次一行(小块重复压缩)的方式。
这 " 一包带走 " 的操作需要更多的中间存储,但能解码的图像数量也更多了。
具体咋回事儿呢?
我们知道,PNG 图像格式编 / 解码基于以下三方面:
CRC-32 和 Adler-32 两种校验和算法
DEFLATE 压缩
二维过滤
Wuffs 对这其中的每一步都进行了优化。
首先,对两种校验和算法施以 SIMD 加速技术。
SIMD 是一种采用一个控制器来控制多个处理器,同时对一组数据中的每一个分别执行相同的操作从而实现空间上的并行性的技术。
其次,0.2 版本 Wuffs 具有与 zlib 库一样的 DEFLATE 实现,而 0.3 版 Wuffs 为现代 CPU(具有 64 位未对齐加载和存储)添加了两个重要的优化:8 字节区块输入和 8 字节区块输出。
DEFLATE 是同时使用了 LZ77 算法与哈夫曼编码的一个无损数据压缩算法。
对于 Wuffs,8 字节区块输入设计的每个内部循环一次读取 64 位可使 DEFLATE 微基准加速多达1.3 倍。
而 8 字节区块输出设计将副本长度舍入为 8 的倍数可以使 DEFLATE 微基准提高多达1.48 倍。
此外,DEFLATE 涉及写入目标缓冲区和写入缓冲区边界的问题。
(经典的 " 缓冲区溢出 " 安全漏洞,类似于从悬崖上奔跑,如何不落入鲨鱼口中)。
此方面,Wuffs 使用和 libpng 相似的蓝 / 红双重实现技术。
蓝 / 红双重实现技术:一种快速的 " 蓝色 " 解压缩(在距缓冲区末端至少 258 个字节或更多字节 时)以及一种缓慢的 " 红色 " 解压缩(反之)技术。
以前面的从悬崖上奔跑做比喻,就是在离崖边还远时尽可能得快跑,离崖边很近时减速刹车。
但同样的技术,为什么 Wuffs 更快?
因为它能一次将几乎所有内容(eg. 300 × 200 RGB 图像的像素的 99%以上)解压缩到一个大的中间缓冲区中,而不是一次只压缩一行到一个小的、可重复使用的中间缓冲区中。
如图所示,几乎所有内容现在都在 " 蓝色 " 区域中解码。
这本身就比 " 红色 " 区域快。
而且在蓝色代码和红色代码之间交替时,Wuffs 也避免了任何指令高速缓存或分支预测变慢的情况。
最后,虽然 Wuffs 和 libpng 都具有 PNG 二维过滤的 SIMD 实现。
但是因为 libpng 将任何自分配的像素行缓冲区对齐到最适合 SIMD 的边界时,对齐这步操作会影响 SIMD 指令的选择和性能。
而 Wuffs 对缓冲区对齐的承诺较少,部分原因是 Wuffs 不具有分配内存的能力,但主要还是因为一次全部解压缩时,zlib 压缩要求放弃例如每行开头 4 字节的对齐。
为什么说最安全?
与 Go 或 Rust 不同,Wuffs 的内存安全是在编译时强制执行的,而不是通过插入运行时再检查。
( ps. 运行时安全检查也可能会影响性能。)
此外,在处理不受信任的(第三方)PNG 图像时,沙盒和多进程体系结构可以提供额外的深度防御。
在上一节描述的三步优化技术也可用来给现有的 libpng、Go/Rust PNG 库等打补丁。
然后就有网友说这样一来 Wuffs 还是不是最快的就难说了……但开发者表示至少在安全性方面,Wuffs No.1 没得说。
最后,Wuffs 版本 0.3.0-beta.1 刚刚发布,但从目前的功能来看,它还不支持颜色空间或伽马校正。
有兴趣的读者可访问参考链接 [ 6 ] 。
参考链接:
[ 1 ] https://nigeltao.github.io/blog/2021/fastest-safest-png-decoder.html
[ 2 ] https://groups.google.com/g/wuffs/c/sAcU-Uvjns8
[ 3 ] https://news.ycombinator.com/item?id=26714831
[ 4 ] https://zhuanlan.zhihu.com/p/196797277
[ 5 ] https://github.com/google/wuffs/blob/main/doc/note/memory-safety.md
[ 6 ] https://github.com/google/wuffs/tree/v0.3.0-beta.1/example
如若转载,请注明出处:https://www.ozabc.com/keji/474726.html