rust - 将 8 个连续字节转换为半字节的最快方法(以 32 位整数编码)
问题描述
这些字节是无符号的,并且都小于 16,因此它们可以放入一个半字节中。我目前正在循环中移动字节,并&
使用0xf
:
pub fn compress(offsets: [u8; 8]) -> u32 {
let mut co: u32 = 0;
for (i, o) in offsets.iter().enumerate() {
co |= ((*o as u32) & 0xf ) << (i * 4);
}
co
}
编译器已经对此做了一些很好的优化:
但也许可以做一些小操作或使用带有 a 的 SIMD 命令u64
来减少操作量?
解决方案
使用bitintr
板条箱,您可以使用pext
:
bitintr::bmi2::pext(x, 0x0f0f0f0f0f0f0f0f)
但是,这仅在英特尔处理器上速度很快。AMD Ryzen 实现了 BMI2,但pext
速度很慢。
这是只有普通代码的替代方案:
pub fn compress(offsets: [u8; 8]) -> u32 {
let mut x = u64::from_le_bytes(offsets);
x = (x | (x >> 4)) & 0x00FF00FF00FF00FF;
x = (x | (x >> 8)) & 0x0000FFFF0000FFFF;
x = (x | (x >> 16));
x as u32
}
这些步骤是这样做的:
start: 0x0a0b0c0d0e0f0g0h
x | (x >> 4): 0x0aabbccddeeffggh
& mask: 0x00ab00cd00ef00gh
x | (x >> 8): 0x00ababcdcdefefgh
& mask: 0x0000abcd0000efgh
x | (x >> 16): 0x0000abcdabcdefgh
as u32: 0xabcdefgh
推荐阅读
- r - 将列名传递给用 R 编写的函数,导入单独的 R Markdown/R 文件
- java - 找到 JSMPP 否定响应 00000001(消息长度无效)
- c++ - 如何避免在我的标题中包含 OpenCV?
- pandas - Pandas groupby 下降前 5% 和后 5% 的数据
- javascript - 图像未出现,整个页面变为空白
- c++ - 如何在向量中的对象上获取析构函数以不引发失败的断言?
- azure - 在 Azure Functions PHP 自定义处理程序中使用 Composer 包
- c# - 使用 LINQ 计算一系列 DateTime 对象之间的平均差异
- node.js - 如何访问通过 res.renderer 传递的变量?
- angular - Angular - Ng-Bootstrap 模态编辑未加载任何数据