【问题标题】:Why is there no optimization for uint8?为什么uint8没有优化?
【发布时间】:2017-07-18 11:27:50
【问题描述】:

所以我一直在研究变量 uint8 的工作原理,我意识到它实际上并不比 int 快!为了进行乘法、除法、加法或减法,程序必须将 uint8 转换为 int,这将使其速度大致相同或稍慢。

为什么 C++ 没有直接对 uint8 实现乘除加减?

【问题讨论】:

  • 优化通常是特定于平台的。在大多数平台中,CPU 架构大于 8 位。它在物理上使用大于uint8 的值。这超出了 c++ 标准的范围。
  • 我怀疑这是在 32/64 位上工作的 CPU 改变了它,而不是 C++。即,编译器在针对您的平台时不能做任何事情。
  • @FrançoisAndrieux 没错,但我想知道为什么 C++ 没有直接将 uint8 加减乘除。
  • @KevinDuarte:C++ 标准并没有禁止这样的操作;事实上,它明确地允许它们。但是该标准没有定义编译器如何实现该操作。由编译器决定如何最好地为该操作生成程序集。
  • IIRC,int 是 CPU 的最佳类型。仅在创建大量对象时使用uint8_t 才有用。

标签: c++ performance visual-studio


【解决方案1】:

我不确定编译器是否会在适当时为 uint8_t 生成 8 位算术运算(不太可能,因为它不太可能更快)。

@harold 提到,我之前说的现在不那么现代了……对于 8 位操作,部分寄存器更新问题现在不再那么严重了。所以,只是大多数 8 位操作并不快。虽然 8 位除法要快一些,但我试图弄清楚为什么 MS 的编译器不会使用它。 (不太确定:由于部分更新问题只是大部分减少而不是完全消除,甚至被 AMD 保留,因此 8 位除法的一个周期优势不值得滥用)。

原文: 在现代 x86 处理器上,8 位操作面临一个称为partial register update 的问题,即您只更改完整寄存器的一部分,这导致false dependency 严重影响性能。


仅供参考,在语言级别上,C++ 中没有小于 int 的整数类型的算术运算。有usual arithmetic promotion提类型。

【讨论】:

  • 错误的依赖只发生在 AMD(Zen 之前,谁知道 Zen 可能会做什么)和 NetBurst,在 P3 和 Core2 及其后代上,8 位寄存器可以独立重命名,问题只会出现当真正依赖于“拆分”寄存器时(因此,在部分更新后使用完整寄存器),并且 即使 在 Haswell 和更新版本上也很快
  • 嗯,它现在仍然是 AMD 的事情,所以它还没有完全成为过去
【解决方案2】:

为什么C++没有直接对uint8实现乘除加减?

因为这样做的最佳方式是特定于平台的。

大多数 CPU 将这些操作作为汇编指令提供,基于使用特定默认大小的整数值(例如 32 位,或 64 位,如 16 位指令的 here 所示),它们可能有也可能没有这样的 @ 指令987654322@ 值。
位大小通常针对 CPU 的缓存衬里机制进行优化。

因此最佳实现取决于可用的目标 CPU 指令,C++ 标准无法涵盖。

【讨论】:

  • @Kevin 这将与我在答案中链接的 ARM 16 位示例相匹配。
猜你喜欢
  • 1970-01-01
  • 2016-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-11
  • 2016-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多