说我正在做一个简单的任务 - 很多。对于这篇文章,我将使用降低mod 2的幂的例子 - 但这可以是任何任务。
有很多种方法,很难确定哪种方法更好。例如,要减少64位无符号整数a
模2^b
,我们可以这样做:
a - (a >> b << b)
a << (64 - b) >> (64 - b)
a & ((1 << b) - 1)
a % (1 << b)
a & array[b]
,其中array[i]
将包含各种((1 << i) - 1)
的值i
。我不想假设array[i]
将在L1缓存中。
也许还有其他人。对于这些方法中的每一种,在查看汇编代码后确定其成本是相当简单的 - 例如两班倒和一个减号;或两个班次,一个字节减去,另一个减号操作被编译器部分优化。
然而,很难确定,在给定的架构中哪些实际上更快。我尝试了以下方法,但失败了:
- 阅读有关架构的文档。当我能找到它时,它给出了一个明确的答案,即一个班次或一个&amp;拿 - 但是,仍然很难说,缓存减去操作需要多少个周期,或者通过将有用数据从缓存中推出以加载array[b]
而导致的性能缺陷有多少数据
- 连续运行相同的代码数百万次。但是,这会导致阵列保留在缓存中,从而提供更快的性能。
- 运行相同的代码数百万次,并在运行之间运行一些代码来放入/读取缓存中的其他数据。但是,由于我在缓存中放入和访问数据,因此运行时间存在很多变化,并且标准偏差太大而不能使结果可靠。
- 感谢@klutt的建议,我将这些方法粘贴到实际代码中,前三种方法似乎具有相同的性能。可能发生的是,当程序等待从缓存中提取另一个值时,所有三种方法都可以完成执行,稍后在程序中。但是,如果程序稍后更改(例如,缓存查找次数较少),则其中一种方法可能会优于其他方法。
如果我不想在每次程序更改时重新访问我的简化模型2 ^ *代码,是否还有另一种更好的方法来衡量哪些更快?
答案 0 :(得分:0)
许多这些实现任务的不同方法(特别是如果它是一个非常简单的任务)将由编译器优化到完全相同的机器代码指令。您是否尝试过探索http://godbolt.org/并查看每种不同方法编译的机器代码指令?这可能会让您更好地了解哪些更好。