为什么我的一个函数运行得这么慢?

我正在编写一些方法的实现,以便在C中使用GMP查找数字的自然日志.我有两个函数,两个函数都有效,但其中一个运行速度比另一个慢很多.问题是,我认为它是速度最慢的那个.

下面是两个相关的函数,而int main的完整文件可以找到here,而所需的ln_2.txt文件是here.

void taylor_log(mpf_t R, 
                const mpf_t N, 
                const mpf_t T)
{
    mpf_t x, y, r, pr, tmp, d;
    int n = 1;
    mpf_init(x);
    mpf_init(y);
    mpf_init(tmp);
    mpf_init(d);

    mpf_sub_ui(x, N, 1);
    mpf_init_set(y, x);

    mpf_init_set(r, x);
    mpf_init_set_ui(pr, 0);    

    mpf_sub(d, r, pr);
    mpf_abs(d, d);
    while(mpf_cmp(d, T) > 0)
    {
        mpf_set(pr, r);

        mpf_mul(y, y, x);
        mpf_div_ui(tmp, y, ++n);
        mpf_sub(r, r, tmp);

        mpf_mul(y, y, x);
        mpf_div_ui(tmp, y, ++n);
        mpf_add(r, r, tmp);

        mpf_sub(d, r, pr);
        mpf_abs(d,d);
    }
    printf("%d\n", n);
    mpf_set(R, r);
 }
void hyperbolic_log(mpf_t R,
                    const mpf_t N,
                    const mpf_t T)
{
    mpf_t x, x2, r, pr, tmp, d;
    int n = 1;   
    mpf_init(x);
    mpf_init(x2);
    mpf_init(tmp);
    mpf_init(d);

    mpf_sub_ui(x, N, 1);
    mpf_add_ui(tmp, N, 1);
    mpf_div(x, x, tmp);

    mpf_init_set(r, x);
    mpf_init_set_ui(pr, 0);

    mpf_mul(x2, x, x);

    mpf_sub(d, r, pr);
    mpf_abs(d,d);
    while(mpf_cmp(d, T) > 0)
    {
        mpf_set(pr, r);
        ++n;

        mpf_mul(x, x, x2);
        mpf_div_ui(tmp, x, ++n);
        mpf_add(r, r, tmp);

        mpf_sub(d, r, pr);
        mpf_abs(d,d);
    }
    printf("%d\n", n);
    mpf_mul_ui(R, r, 2);
}

从理论上讲,第二个函数至少应该运行得更快,因为每个循环的指令更少,并且由于更快的收敛,通常执行更少的循环.这不是我在实践中看到的,因为当我在计算中使用至少33296位计算ln(2)到10000个小数位时,两者都给出了正确的结果,但第一种方法在大约0.150秒内完成,而第二种方法在第二种方法中完成1秒.

我不知道是什么导致一个函数运行速度比另一个慢得多,任何帮助将不胜感激.

编辑:
为清楚起见,我忘了提及在传递给函数之前,将值归一化到范围[0.5,1].对于我已经确认在程序中有效的两个函数,这是相同的,所以从技术上讲,我的问题是当算法提供0.5时.

最佳答案 使用添加的计时功能运行程序,从mpf_mul操作中,对于N = 2,性能命中.

在泰勒案中,

mpf_mul(y, y, x);

xf是-0.5来自mpf_get_d_2exp((long *)& e,N)) – 1,它在gmp结构中的大小为1,无论请求的精度如何.

在双曲线情况下,

mpf_mul(x, x, x2);

x2是0.111 …来自

T  = mpf_get_d_2exp((long *)&e, N))
x  = (T - 1)/(T + 1)
x2 = x * x

在gmp结构中具有所请求精度的大小.在这种情况下的乘法要贵得多.

编辑

实际上,罪魁祸首是mpf_div(x,x,tmp),它迫使gmp使用整个精度.从x计算的x2具有相同的精度,因此mpf_mul较慢.

点赞