繁体   English   中英

哪个整数操作在Rust中具有更高性能的替代方法?

[英]Which integer operations have higher performance alternate methods in Rust?

在Rust中编写将运行数百万次的整数函数(想想像素处理)时,使用性能最高的操作很有用 - 类似于C / C ++。

虽然参考手册解释了行为的变化,但并不总是清楚哪种方法的性能高于标准(参见注释1)整数算术运算。 我假设wrapping_add编译成等同于C的加法。

在标准操作(加/减/乘/模/除/移位/位操作......)中,哪些操作具有更高性能的替代方法,默认情况下不使用?


注意:

  1. 标准,我指的是使用符号a + bi / kc % e等的整数运算。
    编写数学表达式时要使用的内容 - 除非您特别需要使用包装或返回溢出的方法之一。
  2. 我意识到回答这个问题可能需要一些研究。 因此,我很高兴通过查看生成的程序集来进行一些检查,以查看哪些操作正在使用未经检查/原始操作。
  3. 可能是检查/未检查操作之间的速度差异不大,如果是这种情况,我仍然希望能够编写一个“快速”版本的函数来与“安全”版本进行比较,来关于它是否是给定函数的合理选择我自己的结论。
  4. 提到像素处理后,SIMD已成为可能的解决方案。 尽管这是一个很好的建议。 这仍然留给我们使用SIMD 无法优化的情况,因此快速整数算法的一般情况仍然需要考虑。

在标准操作(加/减/乘/模/除/移位/位操作......)中,哪些操作具有更高性能的替代方法,默认情况下不使用?

请注意,Rust是为性能而设计的; 因此,在Debug中检查整数操作时,它们被定义为包装Release中,除非您特别指示编译器。

因此,在具有默认选项的发布模式下,两者之间严格没有性能差异:

  • +wrapping_add
  • -wrapping_sub
  • *wrapping_mul
  • /wrapping_div
  • %wrapping_rem
  • <<wrapping_shl
  • >>wrapping_shr

对于无符号整数,性能因此严格地类似于C或C ++; 但是,对于有符号整数,优化器可能会产生不同的结果,因为有符号整数的下溢/溢出是C和C ++中的未定义行为(gcc和Clang接受-fwrapv标志,即使对于有符号整数也要求包装,但它不是默认值)。

我希望使用checked_*overflow_*saturating_*方法通常会慢一些。


因此,有趣的切线是了解当您翻转开关并明确要求检查算术时会发生什么。

目前,Rust实现1是下溢/溢出检查的精确实现。 每个加法,减法,乘法,...都是独立检查的,优化器不擅长融合这些分支。

具体来说, 精确的实现排除了临时溢出: 5 + x - 5不能优化为x ,因为5 + x可能溢出。 它还排除了一般的自动矢量化。

只有当优化器可以证明没有溢出(通常不能)时,您可能希望重新获得更易于优化的无分支路径。

应该注意的是,在通用软件上,影响几乎不可察觉,因为算术指令只占总成本的一小部分。 然而,当这个比例上升时,它可能非常明显,实际上它出现在与Clang的SPEC2006基准测试的一部分中。

这种开销足以被认为不适合默认激活检查。

1 这是由于LLVM方面的技术限制; Rust实现只委托给LLVM。


将来,我们希望能够获得模糊的支票实施。 模糊实现背后的想法是,不是检查每个操作,而是执行它们并且设置标志或者在下溢/溢出的情况下中断值。 然后,在使用结果之前,执行检查(分支)。

根据Joe Duffy的说法,他们在Midori中有这样的实现,性能影响几乎不可察觉,因此它似乎是可行的。 但是,我还没有意识到在LLVM中有任何类似的努力。

Rust不保证其运营速度。 如果您需要保证,则需要调用汇编程序。

也就是说,当前Rust转发到LLVM,所以你可以调用内在函数,它将1:1映射到LLVM内在函数并使用这些保证。 但是,无论你做什么都不是asm,请注意优化器可能对你认为最优的东西有不同的看法,因此不优化你对LLVM内在函数的手动调用。

也就是说,Rust努力尽可能快,因此您可以假设(或者只是查看标准库的实现)所有具有相同LLVM内在函数的操作将映射到该LLVM内在函数,因此可以像LLVM可以做到这一点。

对于给定的基本算术运算,哪个操作最快是没有一般规则的,因为它完全取决于您的用例。

想像素处理

那么你根本不应该考虑单值操作; 您想要使用SIMD指令。 这些目前在稳定的Rust中不可用,但有些可通过功能门控功能访问,并且所有功能都可通过汇编获得。

是否有可能LLVM将代码优化为SIMD,就像它对clang一样?

正如aochagavia已经回复 ,是的,LLVM将自动调整某些类型的代码。 但是,当您要求最高性能时,通常不希望自己处于优化器的一时兴起。 我倾向于希望在我的普通普通代码中进行自动向量化,然后为我的重数学内核编写直线代码,然后编写SIMD代码并测试速度的正确性和基准。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM