【问题标题】:When and why would I want to use i8 instead of i32?我何时以及为什么要使用 i8 而不是 i32?
【发布时间】:2020-06-02 19:55:52
【问题描述】:

在将变量分配给整数值时,我认为 rust 的默认大小是 32 位,有符号。

如果我正在处理一个适合 16 位(例如 15000)甚至 8 位(例如 120)的值,为什么我不想仍然只使用默认值?

我可能会节省一些内存 - 但这值得考虑吗? 有什么速度优势吗? 如果有的话,还有什么?

【问题讨论】:

标签: rust integer


【解决方案1】:

TL;DR:为了性能。

快速

一般来说,性能是一个复杂的话题,因此选择哪种类型会因用例而异。

不过,一般来说,选择较小的数据类型有两个主要原因:

  • 更好的缓存利用率。
  • SIMD.

更好的缓存利用率

现代 CPU 变得越来越快,而 RAM 并没有跟上。 RAM 的频率与 CPU 的频率相等的日子已经很长了。

这就是缓存的用武之地:典型台式机 CPU 上的 L1、L2 和 L3。问题是物理限制在起作用,它本身限制了这些缓存的大小。典型的 L1 缓存是 32KB 指令/32KB 数据,具有 64 字节的缓存线。

32KB 数据为:

  • 8K i32.
  • 16K i16.
  • 32K i8.

因此,更紧密的数据打包可用于:

  • 在 L1(或 L2、L3、...)中拟合更多数据。
  • 将数据放入 less 个缓存行中。

简而言之,更紧密的封装可以提高缓存利用率。

SIMD

Abseil 瑞士表中最新的哈希表设计之一。

Abseil 的 Swiss Table 主要技巧是创建 16 个元素的组,并为每个组有一个 16 字节的标头,其中包含组中每个元素的 1 字节 (u8) 哈希残差。

单个 SIMD 指令(SSE2 为 16 字节宽)允许查找所有 16 个元素的哈希残差,并确定哪些元素匹配!

这是 SIMD 中的通用主题,指令的操作数非常有限:

  • SSE 是 16 字节(128 位),
  • AVX 是 32 字节(256 位),
  • AVX-512 为 64 字节(512 位)。

使用 SIMD 指令,将元素的大小除以 2 立即意味着在一条指令中处理 2 倍的元素,从而将算法速度提高到 2 倍。

【讨论】:

    【解决方案2】:

    在诸如嵌入式系统、数据传输协议或其他任何网络存储和数据传输是主要关注点的情况下,使用i8i16 和其他此类是一个非常好的主意。此外,编译器会重新排列结构字段以使结构更紧凑,当字段更小时它可以更有效地做到这一点。

    但是对于一般情况,所以无论何时,正如您所说,您的值始终适合 16 位或 8 位...我不确定是否有明确的答案。我会说速度至少最终会依赖于架构。

    用户 trentcl 刚刚在 Discourse 论坛上链接到 this post,我认为这说明了关于一般案例的许多观点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-29
      • 1970-01-01
      • 2020-05-23
      • 2011-10-22
      • 2011-01-21
      • 2015-01-21
      • 2022-12-03
      相关资源
      最近更新 更多