C ++运算符的速度/简单的数学运算

时间:2011-12-14 08:11:02

标签: c++ operators computer-science mathematical-optimization physics-engine

我正在研究物理引擎,并认为这有助于更好地理解执行许多简单或复杂数学运算的速度和性能影响。

  1. 物理引擎的很大一部分正在淘汰不必要的计算,但是在什么时候计算得足够小以至于不需要进行比较检查?

    • 例如:测试两个线段是否相交。在直接进入简单的数学运算之前,是否应该检查它们是否彼此靠近,或者从长远来看,额外的操作是否会减慢进程?
  2. 不同的数学计算需要多长时间

    • 例如:(3 + 8)vs(5x4)vs(log(8))等。
  3. 不平等检查需要多长时间?

    • 例如:>,<,=

6 个答案:

答案 0 :(得分:4)

  1. 您必须进行分析。

  2. 基本操作,如加法或乘法,只需要一个asm指令。

    编辑:根据评论,尽管采用一个asm指令,乘法可以扩展到微指令。

    对数需要更长的时间。

  3. 还有一条asm条指令。

  4. 除非您分析您的代码,否则无法确定您的瓶颈在哪里。

    除非你将数学运算调用数百万次(甚至可能就是这样),否则算法或其他高级优化的良好选择将导致比优化小东西更大的速度增益。

    您应该编写易于阅读且易于修改的代码,并且只有当您对性能不满意时才开始优化 - 首先是高级别,然后才是低级别。

    您可能还想尝试动态编程或缓存。

答案 1 :(得分:2)

嗯,这取决于您的硬件。具有指令延迟的非常好的表是http://www.agner.org/optimize/instruction_tables.pdf

1。这取决于代码很多。另外不要忘记它不仅仅取决于计算,而且还可以预测比较结果的好坏。

2。通常加法/减法非常快,浮点数的乘法稍慢。浮点除法相当慢(如果你需要除以常数c,通常最好预先计算1 / c并乘以它)。除非编译器决定使用SSE,否则库函数通常(我敢说总是)比简单运算符慢。例如,可以使用一条SSE指令计算sqrt()和1 / sqrt()。

3。从大约一个周期到几十个周期。当前的处理器根据条件进行预测。如果预测是正确的,它会很快。但是,如果预测错误,处理器必须丢弃所有预加载的指令(IIRC Sandy Bridge预加载最多30条指令)并开始处理新指令。

这意味着如果你有一个代码,大部分时间都满足条件,它会很快。同样,如果您的代码大多数情况下不满足条件,那么它将很快。简单的交替条件(TFTFTF ......)通常也很快。

答案 2 :(得分:1)

  1. 这取决于您尝试模拟的方案。你有多少个物品,它们有多近?它们是均匀聚集还是分布?你的物体移动很多,或者它们是静止的吗?你必须运行测试。用于快速检查邻近度的可能数据结构是kd-treeslocality-sensitive hashes(可能还有其他)。我不确定这些是否适合您的应用程序,您必须检查数据结构的维护和查找成本是否适合您。
  2. 您必须运行测试。考虑检查您是否可以使用vectorization,或者如果您甚至可以使用CUDA或类似的东西在GPU中运行某些计算。
  3. 同上 - 你必须测试。

答案 3 :(得分:1)

通常可以将不等式检查,递增,递减,位移,加法和减法视为非常便宜。乘法和除法通常稍微贵一些。像对数这样的复杂数学运算要贵得多。

确保平台上的基准测试。注意使用紧密循环的人工测试进行基准测试 - 这往往会给你带来误导性的结果。尝试使用尽可能真实的代码进行基准测试。理想情况下,在实际条件下描述实际代码。

对于线交叉等事物的优化,它取决于数据集。如果您进行了大量检查并且大多数线路都很短,则可能需要快速检查以排除X或Y范围不重叠的情况。

答案 4 :(得分:1)

关于2和3,我可以推荐你Intel® 64 and IA-32 Architectures Optimization Reference Manual。附录C介绍了各种指令的延迟和吞吐量。 但是,除非您手动编写汇编代码,否则编译器将应用自己的优化,因此直接使用这些信息将非常困难。

更重要的是,您可以使用SIMD对代码进行矢量化并并行运行计算。此外,如果您的内存布局不理想,内存性能可能会成为瓶颈。我链接的文件有关于这两个问题的章节。

然而,正如@ Ph0en1x所说,第一步是选择(或编写)一种有效的算法,使其适用于您的问题。只有这样你才能开始怀疑低级优化。

对于1,在一般情况下,我会说如果你的算法以某种方式工作,它有一些可调节的阈值来执行某些测试,你可以做一些分析并打印一些性能图善待,并确定这些阈值的最佳值。

答案 5 :(得分:0)

尽管我知道所有“不平等检查”都需要同时进行 关于其余的计算,我建议你运行一些测试,比如

  1. 采取时间戳A
  2. 进行1,000,000“+”计算(或任何其他)。
  3. 采取时间戳B
  4. 计算A和B之间的差异。
  5. 然后你可以比较计算。

    请记住:

    1. 使用不同的数学库可能会改变它(某些数学库更具有性能导向,而且更精确导向)
    2. 编译器优化可能会改变它。
    3. 每个处理器都采用不同的方式。