Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 实现上的巨大差异?_C++_Performance_Boost_Time Measurement - Fatal编程技术网

C++ 实现上的巨大差异?

C++ 实现上的巨大差异?,c++,performance,boost,time-measurement,C++,Performance,Boost,Time Measurement,我写了一些函数的分布,并使用常态分布来运行我的实现与C++ Boost .< /P>之间的测试。 给定概率密度函数(pdf:) 我是这样写的: double NormalDistribution1D::prob(double x) { return (1 / (sigma * (std::sqrt(boost::math::constants::pi<double>()*2))))*std::exp((-1 / 2)*(((x - mu) / sigma)*((x - mu)

我写了一些函数的分布,并使用常态分布来运行我的实现与C++ Boost .< /P>之间的测试。 给定概率密度函数(pdf:)

我是这样写的:

double NormalDistribution1D::prob(double x) {
    return (1 / (sigma * (std::sqrt(boost::math::constants::pi<double>()*2))))*std::exp((-1 / 2)*(((x - mu) / sigma)*((x - mu) / sigma)));
}

首先,您正在使用
new
动态分配对象:

NormalDistribution1D *n = new NormalDistribution1D(mu, sigma);
double nres = n->prob(x);
如果您像使用boost一样,仅此一项就足以获得相同(或可比)的速度:

现在,我不知道您在
NormalDistribution1D::prob()
中表达表达式的方式是否有意义,但我怀疑以一种更“优化”的方式编写它会有什么不同,因为编译器可以很好地优化算术表达式。如果您使用
--ffast math
开关,它可能会更快,这将给编译器更多的优化自由度


此外,如果
double NormalDistribution1D::prob(double x)
的定义位于另一个编译单元(另一个.cpp文件)中,编译器将无法内联它,这也会造成明显的开销(可能会慢两倍或更少)。在boost中,几乎所有内容都是在头文件中实现的,所以当编译器看起来合适时,内联文件总是会出现。如果您使用gcc的
-flto
开关编译和链接,您可以克服这个问题。

首先,您使用
new
动态分配您的对象:

NormalDistribution1D *n = new NormalDistribution1D(mu, sigma);
double nres = n->prob(x);
如果您像使用boost一样,仅此一项就足以获得相同(或可比)的速度:

现在,我不知道您在
NormalDistribution1D::prob()
中表达表达式的方式是否有意义,但我怀疑以一种更“优化”的方式编写它会有什么不同,因为编译器可以很好地优化算术表达式。如果您使用
--ffast math
开关,它可能会更快,这将给编译器更多的优化自由度


此外,如果
double NormalDistribution1D::prob(double x)
的定义位于另一个编译单元(另一个.cpp文件)中,编译器将无法内联它,这也会造成明显的开销(可能会慢两倍或更少)。在boost中,几乎所有内容都是在头文件中实现的,所以当编译器看起来合适时,内联文件总是会出现。如果使用gcc的
-flto
开关编译和链接,则可以克服此问题。

您没有使用
-ffast math
选项编译。这意味着编译器不能(事实上,不能!)将
(-1/2)*(((x-mu)/sigma)*((x-mu)/sigma))
简化为类似于
boost::math::pdf
中使用的形式

expo = (x - mu) / sigma
expo *= -x
expo /= 2
result = std::exp(expo)
result /= sigma * std::sqrt(2 * boost::math::constants::pi<double>())
expo=(x-mu)/sigma
世博会*=-x
世博会/=2
结果=std::exp(世博会)
结果/=sigma*std::sqrt(2*boost::math::constants::pi())
上述情况迫使编译器在不使用
-ffast\u math
的情况下进行快速(但可能不安全/不准确)计算


其次,与从堆(
new
)和堆栈(局部变量)分配所需的时间相比,上述代码和您的代码之间的时间差最小。您正在计时分配动态内存的成本。

您没有使用
-ffast math
选项编译。这意味着编译器不能(事实上,不能!)将
(-1/2)*(((x-mu)/sigma)*((x-mu)/sigma))
简化为类似于
boost::math::pdf
中使用的形式

expo = (x - mu) / sigma
expo *= -x
expo /= 2
result = std::exp(expo)
result /= sigma * std::sqrt(2 * boost::math::constants::pi<double>())
expo=(x-mu)/sigma
世博会*=-x
世博会/=2
结果=std::exp(世博会)
结果/=sigma*std::sqrt(2*boost::math::constants::pi())
上述情况迫使编译器在不使用
-ffast\u math
的情况下进行快速(但可能不安全/不准确)计算


其次,与从堆(
new
)和堆栈(局部变量)分配所需的时间相比,上述代码和您的代码之间的时间差最小。您正在计算分配动态内存的成本。

计算
(x-mu)/sigma
是浪费<代码>1/2是
.5
。您是否正在测量启用优化的编译代码?如果在循环中多次执行计算,则计时更可靠。目标是至少运行几秒钟,并将总时间除以迭代计数。
(x-mu)/sigma
使用这些值只是第一次测试。但是,我不太了解C++中的优化(我是java开发者),对不起,我的意思是计算<代码>(X-MU)/ Sigma < /C> >两次是浪费的。您现在需要了解是否正在编译优化代码。只有你知道。我们看不到您的编译器选项。您建议我如何编写
(x-mu)/sigma
?我读了一些关于优化的一般资料,现在的结果是:加速:48;而不是自己的实现:46248(为了更好地阅读,我写了问题中的选项)我建议计算该值一次而不是两次计算
(x-mu)/sigma
,这是浪费<代码>1/2是
.5
。您是否正在测量启用优化的编译代码?如果在循环中多次执行计算,则计时更可靠。目标是至少运行几秒钟,并将总时间除以迭代计数。
(x-mu)/sigma
使用这些值只是第一次测试。但是,我不太了解C++中的优化(我是java开发者),对不起,我的意思是计算<代码>(X-MU)/ Sigma < /C> >两次是浪费的。您现在需要了解是否正在编译优化代码。只有你知道。我们看不到您的编译器选项。您建议我如何编写
(x-mu)/sigma
?我读了一些关于优化的一般资料,现在的结果是:加速:48;而不是自己的实现:46248(为了更好地阅读,我编写了这个选项
NormalDistribution1D n(mu, sigma);
double nres = n.prob(x);
expo = (x - mu) / sigma
expo *= -x
expo /= 2
result = std::exp(expo)
result /= sigma * std::sqrt(2 * boost::math::constants::pi<double>())