整数运算与浮点运算

计算科学 稀疏矩阵 表现 浮点 复杂
2021-12-16 07:32:49

我一直在使用一种算法,它使用

  1. 浮点向量的加法,
  2. (浮点稀疏矩阵)x(浮点密集向量)点积

我最近发现,如果我将所有内容(向量和矩阵)设置为整数,我可以从算法中获得相同的功能。细节不平凡且无聊,但我现在知道它有效。

我仍然记得浮点运算是如何工作的(尾数、指数等),对我来说,这似乎要复杂得多的整数运算。因此,我期望修改算法以使用纯整数运算会加快速度。我想知道多少。

现在是我的问题:

  1. 整数运算通常比浮点运算快吗?
  2. 硬件是否专门用于浮动,以至于浮动实际上更可取?
  3. FLOPS 可用于专门量化硬件处理浮点数的能力。我们应该/可以查看什么指标来找出整数的相同之处?
2个回答

StackOverflow 上有一个关于浮点与整数运算的很好的讨论。简而言之,操作的性能很大程度上取决于

  • 处理器架构
  • 数据如何存储在内存中以及访问的顺序
  • 是否(以及使用了哪些)SSE/AVX/AVX2/etc指令(以及效率如何)

这可能提供了一些关于整数类型的普遍性比浮点数更快的问题#1 的一些见解。

然而,FLOPS是众所周知的,因为它是数值软件性能的标准衡量标准。在数值计算中,从浮点类型到整数一般不容易

  • 改变数学运算的性质(除法、三角函数、平方根、特殊函数、大多数线性代数等)
  • 必须实现特殊的(长)整数运算来“模拟”这些操作——这肯定会否定使用整数类型而不是浮点类型的所有可能的好处。

当然,可能有反例,其中整数类型的使用是自然的(例如,图的关联矩阵)。

现在,关于性能指标。来自Wiki的稍微简化的公式:

FLOPS=cores×cyclessecond×FLOPScycle
另外,请参阅CompSci 上的这个问题和 SO 上的这个问题讨论。

现在,为了判断整数运算,我们可以有IPS

IPS=cores×cyclessecond×Instructionscycle

注意区别:对于 FLOPS,我们使用 FLOPS/cycle,而对于 IPS,我们使用每个周期的一般指令同样,它将取决于处理器,如果它实际上每个周期可以执行更多的整数运算(与 FLOPS 相比)。请注意,在许多级别上进行了一些平均:

  • 每个周期平均 # 条指令
  • 对指令顺序的隐藏依赖
  • ...主要是关于数据访问模式——这是现代代码的常见瓶颈。

所以,简而言之,我会回答第一个问题 #2,浮点计算已经优化了很多,所以不自然地使用整数类型不太可能给你带来任何好处。

小额外说明:

我也会研究半精度算术如果您使用的架构可以有效地利用它,它可能会对您的任务有所帮助。

整数运算通常比浮点运算快,但差距远小于 30 年前,那时每个人还在计算 FLOPS。现在 fp-fp 操作和整数-整数操作之间的差异可能是 3 或 5 倍。

但是在这两种情况下,至少如果您的问题变得足够大以至于它们不适合处理器的缓存,那么您是否受到数据从内存加载到处理器的速度的限制。在当今的处理器上,浮点计算是如此之快,以至于如果您正在处理需要来自主存储器的数据的矩阵向量乘积,则处理器有超过 90% 的时间处于空闲状态。所以你的应用程序中更大的问题是你需要多少内存来存储你的矩阵和向量。如果您正在考虑用常规整数(32 位)替换双精度浮点数(64 位),并且您只需要为每个矩阵或向量条目存储一个整数,那么你刚刚节省了 50% 的内存需求,你的算法将运行大约两倍的速度,因为只需要加载一半的内存。但是,如果您打算只存储单精度浮点数(32 位),那么这两种实现之间可能不会有太大的差异。