C++ 我需要计算斯特林';s近似非常快

C++ 我需要计算斯特林';s近似非常快,c++,c,numerical,arbitrary-precision,mpfr,C++,C,Numerical,Arbitrary Precision,Mpfr,我正在为统计抽样编写一个小库,它需要尽可能快地运行。在分析过程中,我发现函数中大约40%的时间用于计算阶乘的对数。我将我的优化工作集中在这一部分上。以下是我的代码(使用): const double AL[8]= { 0.0, 0.0, 0.6931471806, 1.791759469, 3.178053830, 4.787491743, 6.579251212, 8.525161361 }; 无效HGD::mpfr_afc(mpfr_t&ret、const mpfr_t&val){ 如果(m

我正在为统计抽样编写一个小库,它需要尽可能快地运行。在分析过程中,我发现函数中大约40%的时间用于计算阶乘的对数。我将我的优化工作集中在这一部分上。以下是我的代码(使用):

const double AL[8]=
{ 0.0, 0.0, 0.6931471806, 1.791759469, 3.178053830, 4.787491743,
6.579251212, 8.525161361 };
无效HGD::mpfr_afc(mpfr_t&ret、const mpfr_t&val){

如果(mpfr\U cmp\U用户界面(val,7)这里有几点想法。首先,我觉得使用MPFR可能有点过头了。任何多精度库都有巨大的开销。不仅仅是大量的开销,还有巨大的开销。第二个想法是,也许你不需要使用多精度日志函数。也许你可以不用标准日志

如果你不能在双精度浮点运算中进行计算,那么使用线程或其他方法进行并行化肯定会有帮助。你可以尝试使用编译器优化,但我还没有看到真正的改进

您可以尝试的最后一个选项是手动分配内存空间,以便MPFR具有固定的开销。我从未尝试过,所以我不知道这是否有帮助

当数字可以适应机器数据类型时,切换到本机算术

这将是我的第一次尝试。MPFR可能是性能杀手

在我看来,你想计算n!的对数,你已经用斯特林公式近似了

请注意,n!=Gamma(n+1)。存在(似乎)高度优化的函数来计算Gamma函数及其对数。例如:


只有在以上所有性能方面都失败的情况下,我才会使用我自己的粗略近似值。

如果这是幼稚的,我提前道歉,但是如果您进一步细分您的分析,哪一部分这个函数的计算时间最长?日志计算绝对占主导地位。我怀疑你的常数是否为
double
,我希望精度为15-18位。但是,也许最终结果不需要高精度的答案。你用相同的
val
值调用这个函数的频率有多高?可能是d中的一次ozen平均调用该函数。
const double AL[8] =
{ 0.0, 0.0, 0.6931471806, 1.791759469, 3.178053830, 4.787491743,
    6.579251212, 8.525161361 };
void HGD::mpfr_afc(mpfr_t &ret, const mpfr_t &val){

    if(mpfr_cmp_ui(val, 7) <= 0){
        mpfr_set_d(ret, AL[mpfr_get_ui(val, MPFR_RNDN)], MPFR_RNDN);
    }else{
        mpfr_set(ret, val, MPFR_RNDN);
        mpfr_add_d(ret, ret, 0.5, MPFR_RNDN);
        mpfr_log(LV, val, MPFR_RNDN);
        mpfr_mul(ret, LV, ret, MPFR_RNDN);
        mpfr_sub(ret, ret, val, MPFR_RNDN);
        mpfr_add_d(ret, ret, 0.399089934, MPFR_RNDN);
    }
}