关于优化的数学函数,范围和间隔

时间:2014-10-18 21:20:31

标签: c++ c math optimization

我试图围绕如何为游戏和渲染引擎编码数学函数的人们如何有效地使用优化的数学函数;让我进一步解释。

在这些领域中非常需要快速三角函数,有时您可以通过以仅对a有效的不同形式重写sincos或其他函数来优化它们。给定间隔,通常这意味着您的f(x)近似值仅适用于第一象限,即0 <= x <= pi/2

现在f(x)的输入仍然是所有4个象限,但实际公式仅涵盖该间隔的1/4,简单的解决方案是通过分析来检测象限输入并查看它属于哪个范围,如果输入来自不是第一象限的象限,则相应地调整公式的结果。

这在理论上是好的,但这也提出了一些非常糟糕的问题,特别是考虑到你正在做这一切以从你的CPU中偷走几个周期这一事实(你也得到了一致的实现,这不是平台依赖于英特尔x86 asm中的硬编码fsin仅适用于x86且具有一定的误差范围,所有这些在其他平台上可能与其他asm指令不同),因此您应该保持并发和高速工作绩效水平。

我无法绕过&#34;切换案例&#34;象限解决方案是:

  • 它只是阻止了可能的优化,即memoization,考虑到你通常希望将switch-case置于实际计算f(x)的相同函数中,可能通过实现公式来改善情况f(x)在所述函数之外,但这将导致为任何给定的数学库维护的函数数量翻倍
  • 通过并发执行增加更多分支的可能性
  • 一般来说,没有更好,干净,干燥的代码,条件语句往往是潜在的错误来源,我不太喜欢开关案例和类似的事情。

假设我可以在C或C ++中实现我的跨平台f(x),那么这个领域的程序员通常如何解决转换和映射输入的问题,通过实际实现的结果象限? / p>

1 个答案:

答案 0 :(得分:2)

注意:在下面的回答中,我会非常一般地谈论代码。

  

假设我可以用C或C ++实现我的跨平台f(x),那么这个领域的程序员通常如何解决转换和映射输入的问题,通过实际实现将象限转换为结果?

对此的一般答案是:以最明显和最简单的方式实现您的目的。

我不完全确定我会遵循你的大多数论点/问题,但我有一种感觉,你正在寻找真正不存在的问题。您真的是否需要重新实现三角函数?不要陷入NIH的陷阱(不是在这里发明)。

   直截了当 解决方案是检测象限

是的!我喜欢直截了当的代码。代码一目了然,它的作用非常明显。现在,有时候,有时候,你必须做一些疯狂的事情来让它做你想做的事情:性能,或避免你的控制之外的错误。但第一个版本应该是最明显和简单的代码,可以解决您的问题。从那里你进行测试,分析和基准测试,如果(仅当)你发现了性能或其他问题,那么你会进入疯狂的事情。

  

这在理论上是好的,但这也带来了一些非常糟糕的问题,

在大多数情况下,我会说理论在实践中很好,我绝对不会看到任何&#34;坏&#34;问题。特定极端情况或设计要求中的次要问题最多。

您的一些具体评论中的一些内容:

  • f(x)的近似值仅适用于第一象限:是,并且有多种原因。简单来说,大多数三角函数都具有同一性,因此您可以轻松地使用这些函数来减少输入参数的范围。这很重要,因为许多数值技术仅适用于特定范围的输入,或者对于小输入更精确/高效。接下来,对于非常大的输入,您无论如何都必须调整范围,以使大多数数值技术工作或至少在相当长的时间内工作并具有足够的精度。例如,查看cos()的泰勒展开,看看对于大输入和小输入充分收敛需要多长时间。
  • 它只是阻止了可能的优化:如今,你的c ++编译器很可能在优化方面比你更好。有时它不是,但一般程序是让编译器进行优化,只进行手动优化,测量并证明您需要它。这几天通过查看代码来判断哪些代码更快是非常不直观的(你可以阅读有关性能问题的所有问题以及一些根本原因有多疯狂)。
  • 即memoization:我从未见过double函数的memoization。想想在0和1之间有多少双打。现在在精度降低的情况下你可以利用它,但这很容易实现为针对这种情况量身定制的自定义功能。考虑到这一点,我并不完全确定如何为double函数实现备忘,这实际上意味着什么,并且在此过程中不会失去准确性或性能。
  • 通过并发执行增加更多分支的概率:我不确定我是否会以并发方式实现三角函数,但我认为完全有可能获得一些性能优势。但同样,编译器在优化方面通常比你更好,所以让它完成它的工作然后基准/配置文件,看你是否真的需要做得更好。
  • 不会产生更好,干净,干燥的代码:我不确定您在这里究竟是什么意思,或者干什么代码&#34;干代码&#34;就此而言。是的,有时你可能会因太多或太复杂的if / switch块而遇到麻烦但是我不能在这里看到4个象限的简单检查......这是一个非常简单和简单的案例。
  • 所以对于任何平台我都得到相同的y来获得相同的x值:我的猜测是得到&#34;确切&#34;多个平台和系统中所有53位double的值都不可能实现。如果只有52位正确,结果是什么?这将是一个很好的区域,可以进行一些测试,看看你得到了什么。

我在C中使用了三角函数超过20年,99%的时间我只使用提供的内置函数。在极少数情况下,我需要通过测试或基准测试证明更多性能(或准确性),然后我才真正为自己的特定情况推出自己的自定义实现。我不会重写<math.h>函数的全部内容,希望有一天我可能需要它们。

我建议尝试使用尽可能多的方法编写其中一些函数,并进行一些准确性和基准测试。这将为您提供一些实用知识,并为您提供有关您是否确实需要重新实现这些功能的一些硬数据。至少,这应该为您提供实施这些类型功能的实践经验,并且在此过程中有机会回答您的许多问题。