【问题标题】:Performance of bool vs int arraybool 与 int 数组的性能
【发布时间】:2017-12-04 12:57:22
【问题描述】:

在玩 Go 中的一些简单代码时,我注意到使用 bool 数组而不是 int 数组(仅使用 0/1 的值)具有相当显着的加速。

  • funcUsingBool - 1.397s
  • funcUsingInt - 1.996s

我希望它们都提供相同的性能,因为在机器级别没有本机 bool 类型,所以我希望编译器生成类似的汇编代码。

由于差异很大,我对这个结果的有效性持怀疑态度。

我正在使用命令“go build filename.go”进行构建,但我不确定 gcc 的“-O3”的等效标志是什么。

func funcUsingBool(n int) int {
    if n < 1 { return 0 }

    notPrime := make([]bool, n+1)
    count := 1
    for i := 3; i < n; i = i + 2 {
        if notPrime[i] { continue }
        count++
        k := 2 * i
        for k <= n {
            notPrime[k] = true
            k += i
        }
    }
    return count
}

func funcUsingInt(n int) int {
    if n < 1 { return 0}

    notPrime := make([]int, n+1)
    count := 1
    for i := 3; i < n; i = i + 2 {
        if notPrime[i] == 1 { continue }
        count++
        k := 2 * i
        for k <= n {
            notPrime[k] = 1
            k += i
        }
    }
    return count
}

【问题讨论】:

  • 为什么在使用不同大小的值时不会有一些差异?
  • 没有原生 bool 类型,是的,但这仍然使 bool 1 字节和 int 4 或 8 字节。
  • 对问题的分数感到惊讶(否定)。严肃的问题:我是否会降低“GO-ers”对一个琐碎话题的期望讨论水平,应该在其他地方问这样的问题,还是我的措辞很差和缺乏?
  • @twosan:x86(和大多数其他 CPU)可以有效地处理字节元素。在当前的 Intel CPU 上,将字节的零扩展或符号扩展加载到 64 位寄存器中与 4 字节或 8 字节的加载一样便宜。字节商店也很便宜。只有早期的 Alpha AXP CPU 只能加载对齐的字,并且必须移位/屏蔽才能获取字节。
  • 使用位图会更昂贵,因为将位设置为true 需要对包含它的字节进行读取-修改-写入,这比简单的存储更昂贵。但是,当您的阵列变得足够大时,这是值得的,因为在 L1 或 L2 缓存中安装以避免缓存未命中是值得的,每次写入操作的额外 CPU 开销都是值得的。 (从内存中测试一个位仍然很便宜,尤其是在 x86 上)。

标签: performance go


【解决方案1】:

查看程序集输出 (go run -gcflags '-S' test.go) 有一些不同:

布尔:

0x0075 00117 (test.go:11)   MOVBLZX (AX)(BX*1), DI
0x0079 00121 (test.go:11)   TESTB   DIB, DIB

诠释:

0x0075 00117 (test.go:28)   MOVQ    (AX)(BX*8), DI
0x0079 00121 (test.go:28)   CMPQ    DI, $1

字节/uint8:

0x0075 00117 (test.go:28)   MOVBLZX (AX)(BX*1), DI
0x0079 00121 (test.go:28)   CMPB    DIB, $1

在 Go 1.8.* 上,其余的程序集对我来说几乎相同。

所以:1) 数据类型的大小不同 2) 操作不同

【讨论】:

  • 不,布尔不表示为一个单词,它表示为一个字节,因此“移动字节”与“移动四字”。 play.golang.org/p/KVCTusPDOT
  • 是的,我立即编辑了 ;-) - [支持您在上面发表评论,int/bool 大小不同]
  • 感谢您的分析!
  • @PeterCordes:很公平。测试(至少在某些 CPU 上)似乎表明位向量几乎总是至少与字节向量一样快,而且你根本不需要一个非常大的问题。显示优势。请参阅:codereview.stackexchange.com/q/117880/489 进行一项测试。
  • @PeterCordes:就埃拉托色尼筛网的代码而言,我自己在这方面做了一些比较。 stackoverflow.com/a/16738887/179910
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 2011-02-22
  • 2019-09-08
  • 2013-12-31
  • 1970-01-01
  • 2020-03-04
  • 2014-08-27
相关资源
最近更新 更多