[英]When to use std::complex<long double> vs. own complex data type (struct etc..)
[英]gsl_complex vs. std::complex performance
我正在编写一个程序,该程序在很大程度上取决于复杂的加法和乘法。 我想知道应该使用gsl_complex
还是std::complex
。
我似乎没有找到在线比较GSL复杂算术与std::complex
相比要好多少的比较。 一个基本的谷歌搜索也没有帮助我找到GSL complex的基准页面。
我编写了一个20行的程序,该程序生成两个复数的随机数组(其中1e7个),然后使用<ctime>
clock()
检查加法和乘法所花的clock()
。 使用这种方法(没有优化编译器),我知道gsl_complex_add
和gsl_complex_mul
分别几乎是std::complex<double>
的+
和*
std::complex<double>
。 但是我以前从未做过这样的事情,所以这是否就是您检查哪种方法更快?
任何链接或建议都会有所帮助。 谢谢!
编辑:
好的,所以我再次尝试使用-O3标志,现在结果非常不同! std::complex<float>::operator+
速度是gsl_complex_add
两倍gsl_complex_add
,而gsl_complex_mul
速度是std::complex<float>::operator*
1.25倍。 如果我使用double,则gsl_complex_add
比std::complex<double>::operator+
快30%,而std::complex<double>::operator*
则比gsl_complex_mul
快10%。 我只需要浮点级精度,但是我听说 double更快(并且内存对我来说不是问题)! 所以现在我真的很困惑!
打开优化。
与您链接的任何库或函数集都将使用优化功能进行编译(除非开发人员的姓名为Kermit,瑞典厨师,佩吉小姐(项目经理)和Cookie Monster(测试人员),换句话说,开发团队是一堆的布偶)。
由于std::complex
使用模板,因此它是由您提供的编译器设置来编译的,因此代码不会得到优化。 因此,您的问题确实是:“当函数X经过优化编译而Y却未经优化编译时,为什么函数X会比做同样事情的函数Y快?” -答案很明显:“优化几乎一直都在起作用!” (如果大多数情况下优化都不起作用,那么编译器开发人员将可以轻松得多)
编辑:所以我的上述观点刚刚被证明。 请注意,由于模板可以内联代码,因此它通常比外部库更有效(因为编译器可以将指令直接插入流中,而不是调用另一个函数)。
对于float
vs. double
, float
比double
慢的唯一时间就是只有double
硬件可用,并且在float
和double
之间添加了两个“缩短”和“加长”功能。 我不知道任何此类硬件。 double
具有更多位,因此应花费更长的时间。
编辑2:
当选择“一种解决方案而不是另一种解决方案”时,有很多因素。 绩效是一种(在某些情况下,最重要,在其他情况下则不是)。 其他方面是“易用性”,“可用性”,“适合项目”等。
如果仅查看性能,则有时可以运行简单的基准测试来确定一种解决方案比另一种更好或更差,但是对于复杂的库[不是“实数和虚数”类型的复数,而是“复杂的”],有时会有一些优化处理大量数据时,如果使用不太复杂的解决方案,则“大数据”将无法实现相同的性能,因为在解决“大数据”类型问题上花费的精力更少。 因此,如果您有一个“简单”基准测试,可以对少量数据进行一些基本计算,并且实际上您将要运行更大的数据集,则小型基准测试可能无法反映实际情况。
而且,我或其他任何人都无法告诉您哪种解决方案可以在您使用数据集的系统上为您带来最佳性能,除非我们可以访问您的数据集,否则请确切知道您的性能是哪些计算(即(其中包含您的代码),并且具有使用两个“包”运行该代码的经验。
继续进行其余的标准(“易用性”等),这些标准更多是基于“个人意见”,因此首先不适合解决SO问题。
这个答案不仅取决于优化标志,还取决于用于编译GSL库和特定代码的编译器。 示例:如果使用gcc编译gsl并使用icc编译程序,那么您可能会看到一个(显着的)差异(我已经用std :: pow vs gsl_pow进行了此测试)。 此外,。 ./configure
生成的标准makefile不会通过积极的浮点优化来编译GSL(例如:在gcc中不包含快速运算符标志),因为某些GSL例程(例如,微分方程求解器)在以下情况下无法通过严格的精度测试:这些优化是存在的。
GSL的优点之一是库的模块化。 如果不需要双重精度,则可以使用积极的浮点数优化分别编译gsl_complex.h
, gsl_complex_math.h
和math.c
(但是您需要删除math.c中的#include <config.h>
行) 。 另一种策略是使用积极的浮点数优化来编译整个库的单独版本,并测试对于您的特定问题而言准确性是否不是问题(这是我最喜欢的方法)。
编辑:我忘了,更不用说gsl_complex.h
也有一个浮动版本gsl_complex
typedef struct
{
float dat[2];
}
gsl_complex_float;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.