多项式运算性能比对

有原始按照每次项相乘的方式来计算和使用horner方法进行多项式求和运算;

  1. 使用原始计算方法,代码如下:

double poly_original(double *a, double x, long degree)

{

    long i;

    double result = a[0];

    double xpwr = x;

    for(i = 1; i <= degree; i++ )

    {

       result += a[i] * xpwr;

       xpwr = x * xpwr;

    }

 

    return  result;

}

 

  1. 使用horner 方法计算方法和代码如下:

公式为:

 

代码如下:

double poly_horner(double *a, double x, long degree)

{

    long i;

    double result = a[degree];

    for(i = degree - 1; i >= 0; i-- )

    {   

       result = a[i] + x * result;

    }   

 

    return  result;

}

 

比较这两个方法的性能,我们直觉上会发现,原始的方法的乘法运算的数量是第二种方法的两倍,因此,按理说,第一种方法应该要慢很多才对,实际上,第一种方法运行的速度还是要快一些。

它们的objdump汇编代码如下:黄色是每次循环运行的代码

原始计算方法:

000000000040077d <_Z13poly_originalPddl>:

  40077d:   f2 0f 10 17             movsd  (%rdi),%xmm2

  400781:   48 85 f6                test   %rsi,%rsi

  400784:   7e 23                   jle    4007a9 <_Z13poly_originalPddl+0x2c>

  400786:   66 0f 28 c8             movapd %xmm0,%xmm1

  40078a:   b8 01 00 00 00          mov    $0x1,%eax

  40078f:   66 0f 28 d9             movapd %xmm1,%xmm3

  400793:   f2 0f 59 1c c7          mulsd  (%rdi,%rax,8),%xmm3

  400798:   f2 0f 58 d3             addsd  %xmm3,%xmm2

  40079c:   f2 0f 59 c8             mulsd  %xmm0,%xmm1

  4007a0:   48 83 c0 01             add    $0x1,%rax

  4007a4:   48 39 c6                cmp    %rax,%rsi

  4007a7:   7d e6                   jge    40078f <_Z13poly_originalPddl+0x12>

  4007a9:   66 0f 28 c2             movapd %xmm2,%xmm0

  4007ad:   c3                      retq

从上面的代码分析,关键数据路径是mulsd  (%rdi,%rax,8),%xmm3和addsd  %xmm3,%xmm2,而mulsd  %xmm0,%xmm1、add    $0x1,%rax,cmp    %rax,%rsi,  movapd %xmm1,%xmm3,都可以在它运行的期间完成。

Horner方法:

00000000004007ae <_Z11poly_hornerPddl>:

  4007ae:   f2 0f 10 0c f7          movsd  (%rdi,%rsi,8),%xmm1

  4007b3:   48 83 ee 01             sub    $0x1,%rsi

  4007b7:   78 13                   js     4007cc <_Z11poly_hornerPddl+0x1e>

  4007b9:   f2 0f 59 c8             mulsd  %xmm0,%xmm1

  4007bd:   f2 0f 58 0c f7          addsd  (%rdi,%rsi,8),%xmm1

  4007c2:   48 83 ee 01             sub    $0x1,%rsi

  4007c6:   48 83 fe ff             cmp    $0xffffffffffffffff,%rsi

  4007ca:   75 ed                   jne    4007b9 <_Z11poly_hornerPddl+0xb>

  4007cc:   66 0f 28 c1             movapd %xmm1,%xmm0

  4007d0:   c3                      retq  

从上面的代码分析,关键数据路径是mulsd  %xmm0,%xmm1和addsd  (%rdi,%rsi,8),%xmm1。

因此,从上面看,它们的性能应该是等同的才对。

下面是我的测量数据:

root@opzoon-All-Series:/data_1/songqing/for_test/keyDataPath# ./a.out

keyDataPath.cpp(66): original   cost 25776997 microsecond

keyDataPath.cpp(76): horner  cost 27069789 microsecond

 

root@opzoon-All-Series:/data_1/songqing/for_test/keyDataPath# ./a.out

keyDataPath.cpp(66): original   cost 25915710 microsecond

keyDataPath.cpp(76): horner  cost 26932413 microsecond

 

root@opzoon-All-Series:/data_1/songqing/for_test/keyDataPath# ./a.out

keyDataPath.cpp(66): original   cost 25804754 microsecond

keyDataPath.cpp(76): horner  cost 27919597 microsecond

是,为什么原始方法会稍微快一点呢???

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值