4个版本
0.1.0 | 2024年5月16日 |
---|---|
0.0.3 | 2024年5月15日 |
0.0.2 | 2024年5月3日 |
0.0.1 | 2024年4月2日 |
340 在 数据结构
每月116 次下载
用于 heapbuf
195KB
5K SLoC
uintx
Rust中的未对齐整数类型,具有算术运算
实现类型
- u24
- u40
- u48
- u56
- u72
- u80
- u88
- u96
- u104
- u112
- u120
这些类型中的每一个都实现了并提供了与u32相同的所有功能。除此之外,它们还重载了下一个最大对齐数的所有运算符。示例
#[test]
fn test() {
let mut num : u24 = u24::from(12u32);
num += 1u32;
num = num + 1u32;
num += u24::from(4);
num = num + u24::from(4);
assert_eq!(num, 22)
}
可选的crate功能
num_traits_support
启用此功能会导致此crate的所有类型都实现PrimInt特性和num_traits crate所需的所有超特性和。
ux_support
启用此功能将启用ux crate提供的所有数值类型的Into和From转换。如果您需要从内存块中读取未对齐数据但需要执行有符号数学运算,这非常有用。如果您的基础代码库已经使用ux crate,这也很有用。
从uintx到ux以及反之的转换永远不会失败。它们总是将值截断。因此,将u24转换为ux::u12永远不会失败,但超出第12位的所有位都将被丢弃。将ux::u28转换为u24也是如此。这将丢弃超出第24位的所有位。
intx_support
启用此功能将启用intx crate提供的所有数值类型的Into和From转换。这主要在您需要具有精确sizeof的有符号数时很有用。
请注意,intx crate不实现任何算术运算,因此这可能在您已经使用intx的代码库中更有用。
unsafe_fetch
此功能为每种类型提供了一些函数,用于使用比内存安全的std::ops更少的fetch指令(和更少的指令总体上)执行算术运算。这全部取决于CPU如何从内存中获取数据,因此您的性能可能取决于CPU架构。我主要针对x86_64实现此功能。
普通加法运算2个u24整数会编译成2个fetch+1个shift对每个u24,然后是一个加法操作,然后存储结果2个stores+1个shift。这是内存安全的,但不是最快的。
函数:u24::unsafe_add_with_aligned_into_aligned(u24, u32) -> u32
这将编译成1次fetch和1次add操作,然后是1次store操作,比上面的方法更快。请注意,这个函数隐式地将输出转换为u32。这个函数也有变体,可以输出u24或接受2个u24作为输入。它们需要更多的指令,但仍然少于内存节省的"+"操作符。
为什么这些不安全的函数不是内存安全的?
你可能已经知道,CPU没有指令可以只从内存中获取3个字节。不安全的函数总是获取下一个最大的可能类型。在u24中,这将是一个u32。因此,这个函数将读取比缓冲区(切片/vec)更多的1个字节。额外的字节对计算结果没有影响,但它仍然会被读取。这可能会导致你的应用程序段错误或产生其他意外的后果(例如,内存映射I/O可能会做些奇怪的事情)。这基本上是为了操作那些大小是下一个最大对齐整数可整除的填充缓冲区。所以对于u24,缓冲区(切片/vec)的大小应该是字节可被4整除,以便安全地使用不安全的操作。我不建议在栈变量上使用它(栈的布局很难/不可能预测)。如果你不想处理这个问题,我建议你不要使用不安全的函数,而要坚持使用安全的std::ops。我也建议在使用不安全的函数时,使用反汇编器验证编译后的代码。某些整数(取决于大小/架构)使用不安全的函数时并不更快。不允许所有原始类型进行未对齐内存访问的CPU架构,如果在使用此功能时,可能会引发SIGBUS。再次建议只使用x86_64。
替代方案
如特性中所述,intx和ux库提供与这个crate类似的功能。
我不使用它们的个人原因如下
intx
- 没有实现算术操作。如果你需要的东西不仅仅是println()或者转换为对齐类型,那么你将不得不自己实现一切。
- 没有为任何类型实现限制构造函数。只有一个try_into,这需要错误处理。
- 例如,如果你需要将数字0xAFFFF转换为U24,你需要使用try_into或from_ne_bytes。
- 你不能有任何intx类型的常量,因为构造函数都不是const。
ux
- 值的大小并不像它们声称的那样。例如,ux::u24在内存中有4个字节,这使得它们不适用于从文件读取的现有未对齐数据的切片。
- 所有u63/i63以上的类型都没有正确实现?
- 那些值的所有Into和From实现都缺失。
- 我需要u72等类型正常工作。
制作这个库的动机
这个库是为了帮助处理大量的RGB、BGR、CMYKOG、CMYKOGV等像素缓冲区,这些缓冲区以奇特的"像素"格式存在,在这些格式中,在像素表示有效值之前必须执行算术操作。这样做会使用大量的& &|和移位操作,导致代码可读性极差。
依赖
~0-320KB