2012-04-13 27 views
4

我一直在试图产生的Jacobi theta functionsNewton's method分形 - 我与mpmath尝试需要很长的时间,所以我试图编码它C.加速θ函数评价为牛顿法分代

用于源生成以下图像是在这里:http://owen.maresh.info/allegra.c和将与 GCC allegra.c -o Allegra的-lm编译,然后应被调用作为./allegra> jacobi.pnm

http://owen.maresh.info/jacobi.png

这样: *有没有方法可以加速评估 - 这花了超过半小时的时间来制作此图片? (我希望能够用不同的nome快速制作这些图像,以便我可以制作电影) *我知道我在theta函数定义中犯了一个错误,但我很难找到原因不连续性。

为了参考的目的,该图像是由做于θ的标准牛顿法产生(Z,0.001-0.3019 * I)

+1

你介意我你的代码传给苹果作为一个例子编译时运行速度慢的应用程序用他们新的'clang' C编译器而不是他们的gcc。 – 2012-04-14 19:41:56

+0

没问题。我打算用icc尝试一下。 – 2012-04-14 20:22:23

+0

'icc'是个好主意。我好奇你在'gcc'上看到了多少改进。 – 2012-04-14 23:47:43

回答

3

首先尝试使编译器优化与-O3和/或-fast。我的系统上的快速测试显示的一个因素或3的性能提升

此外,随着代码的变化试验,以提高性能时,它是有益的更快的运行时间,也许改变你的主循环for(a=0;a<10 /* 512*/ ;a++)

而且注意:GCC支持complex numbers看手册页complexcpow,并且cexp,包括文件/usr/include/complex.h

我异形的应用,并认为这是花费大部分时间都在powc()。不幸的是,当我改变powc()从数学库中使用cpow()时,它比你的实现运行得慢。

如果您正在运行的系统具有多个内核,那么通过将外部主循环与OpenMP并行化,挂钟时间可能会相当容易地被降低。但是,当您为动画生成图像帧时,仅用每个帧生成一个单独的进程(我喜欢xargs -P # -n 1用于此类粗粒度并行化)就可能是最有效的。

+0

顺便说一下,我的直觉是,没有人真的在c99标准中使用复杂的数据类型来处理任何事情,而且它只是被添加到语言中,因为有人认为这将是一个好主意时间。 (作为一个双重保护:我对某种特殊功能ASIC很感兴趣,因为这些功能(Jacobi)theta在软件中被重新实现了agazillion次,所有的软件实现都很流畅) – 2012-04-15 01:32:08

+0

我以为'gcc'有一段时间的复杂支持C99。但是,如果大多数'complex'的重型用户仍在使用fortran,我不会感到惊讶。 – 2012-04-15 20:54:59

3

当您提到此在IRC上,我心情很奇怪,花了一段时间来优化它。现在在我的Mac上至少快4倍,不计算编译器优化标志,在其他一些平台上更是如此。

我是...无知,当涉及到更高的数学,但我知道一些关于优化的东西。我相信这里的计算与原始计算相同,除了用expc()代替系统cexp()来实现,它会产生相同的输出。你可以决定它是否仍然在数值上足够稳定。

正如布莱恩·斯威夫特指出,powc()是昂贵的,这是因为日志()和POW(的)功能

那名大胜利的东西:

  • 在pjtheta计算()和pjtheta3()可以结合使用
  • 计算可以在newt()中作为内部循环,并且其中一些可以从内部循环或两个循环中移出
  • cpow()对于Brian (和我),但cexp()肯定比你的代码快,至少o在我的机器。尝试一下两种方式
  • -ffast,数学的编译器选项删除支持标准符合不良行为数量和加快了很多东西

另一个大的胜利是转换算术CEXP()和CPOW( )转换为单精度,但这会产生稍微不同的结果,您可能会也可能不会关心。

您可能无法识别该程序了,而是它在:

https://github.com/cgull/allegra.git

我注意到一对夫妇更多的东西,敲了另外25%-33%出来的(天哪,这是一个迭代函数会聚!)

我敢肯定,别人谁懂得高等数学比我能找到的还有性能的另一个2-4x ...