gsl_complex vs. std :: complex performance

时间:2013-09-07 09:59:52

标签: c++ complex-numbers gsl

我正在编写一个程序,该程序很大程度上取决于复杂的加法和乘法。我想知道是否应该使用gsl_complexstd::complex

我似乎没有在网上找到与std::complex相比GSL复杂算术有多好的比较。一个基本的谷歌搜索并没有帮助我找到GSL综合体的基准页面。

我编写了一个20行程序,生成两个随机的复数数组(其中1e7个),然后使用clock()中的<ctime>检查加法和乘法的持续时间。使用这种方法(没有编译器优化)我知道gsl_complex_addgsl_complex_mul几乎是std::complex<double> +*的两倍} 分别。但我以前从未做过这种事情,所以这甚至是你检查哪种更快的方式呢?

任何链接或建议都会有所帮助。谢谢!

编辑:

好的,所以我再次尝试使用-O3标志,现在结果非常不同! std::complex<float>::operator+的速度是gsl_complex_add的两倍,而gsl_complex_mul的速度是std::complex<float>::operator*的1.25倍。如果我使用double,gsl_complex_addstd::complex<double>::operator+快约30%,而std::complex<double>::operator*gsl_complex_mul快约10%。我只需要浮点级精度,但是我heard双倍更快(并且内存对我来说不是问题)!所以现在我真的很困惑!

2 个答案:

答案 0 :(得分:4)

启用优化功能。

您链接的任何库或一组函数都将被编译为 WITH 优化(除非开发人员的名字是Kermit,瑞典厨师,Miss Peggy(项目经理)和Cookie Monster(测试人员) - 换句话说,开发团队是一堆Muppets)。

由于std::complex使用模板,因此它是由您提供的编译器设置编译的,因此代码将不会被优化。所以你的问题是“为什么函数X比函数Y更快做同样的事情,当函数X用优化编译而Y编译没有优化?” - 这应该是非常明显的回答:“优化几乎在所有时间都有效!” (如果优化在大多数情况下都不起作用,那么编译器开发人员将会有更多的时间)

编辑:所以我的上述观点已被证实。请注意,由于模板可以内联代码,因此它通常比外部库更有效(因为编译器可以直接将指令插入到流中,而不是调用另一个函数)。

关于floatdouble的关系,float慢于double的唯一时间是,只有double个硬件可用,有两个在floatdouble之间添加“缩短”和“延长”的功能。我不知道任何这样的硬件。 double有更多的位,所以它应该花更长的时间。

Edit2:

在选择“一种解决方案而非另一种解决方案”时,有很多因素。性能是一个(在某些情况下,最重要的,在其他情况下不是)。其他方面是“易用性”,“可用性”,“适合项目”等。

如果仅查看性能,有时可以运行简单的基准测试来确定一个解决方案比另一个更好或更差,但是对于复杂的库[不是“真实和虚构”类型的复数,而是“复杂”],有时会对处理大量数据进行优化,如果使用不太复杂的解决方案,“大数据”将无法实现相同的性能,因为在解决“大数据”类型问题上花费的精力更少。因此,如果你有一个“简单”的基准测试,可以对一小组数据进行一些基本的计算,而实际上你将运行一些更大的数据集,那么小的基准测试可能无法反映现实。

除非我们能够访问您的数据集,否则我或其他任何人都无法告诉您哪种解决方案会在您的系统上为您提供最佳性能,除非我们能够准确了解您的性能(即是,几乎有你的代码),并有使用两个“包”运行它的经验。

继续使用其他标准(“易用性”等),这些更基于“个人观点”,因此首先不适合SO问题。

答案 1 :(得分:1)

这个答案不仅取决于优化标志,还取决于用于编译GSL库和特定代码的编译器。示例:如果您使用gcc编译gsl并使用icc编译程序,那么您可能会看到(显着)差异(我已经使用std :: pow vs gsl_pow进行了此测试)。此外,由./configure生成的标准makefile不会使用积极的浮点优化来编译GSL(例如:它不包括gcc中的快速数学标记),因为某些GSL例程(例如,微分方程求解器)未能达到严格的精度测试何时存在这些优化。

关于GSL的一个重点是图书馆的模块化。如果您不需要双精度,那么您可以使用积极的浮点数优化分别编译gsl_complex.hgsl_complex_math.hmath.c(但是您需要删除行#include <config.h> math.c)。另一个策略是使用激进的浮点数优化来编译整个库的单独版本,并测试精度是否是您特定问题的问题(这是我最喜欢的方法)。

编辑:我忘了提及gsl_complex.h也有gsl_complex的浮动版

typedef struct
  {
    float dat[2];
  }
gsl_complex_float;