c - Beagle Bone Black 的 float 与 double 性能测试

标签 c profiling beagleboneblack

我正在 Beaglebone Black 上进行一些图像处理,并且对在我的算法中使用 float 与 double 的性能增益感兴趣。

我尝试为此设计一个简单的测试:

main.c

#define MAX_TEST 10
#define MAX_ITER 1E7
#define DELTA 1E-8 

void float_test()
{
    float n = 0.0;
    for (int i=0; i<MAX_ITER; i++)
    {
        n += DELTA;
        n /= 3.0;
    }
}


void double_test()
{
    double n = 0.0;
    for (int i=0; i<MAX_ITER; i++)
    {
        n += DELTA;
        n /= 3.0;
    }
}


int main()
{
    for (int i=0; i<MAX_TEST; i++)
    {
        double_test();
        float_test();
    }

    return 0;
}

运行为:

gcc -Wall -pg main.c  -std=c99
./a.out
gprof a.out gmon.out -q > profile.txt

个人资料.txt:

granularity: each sample hit covers 4 byte(s) for 0.03% of 35.31 seconds

index % time    self  children    called     name
                                                 <spontaneous>
[1]    100.0    0.00   35.31                 main [1]
               18.74    0.00      10/10          float_test [2]
               16.57    0.00      10/10          double_test [3]
-----------------------------------------------
               18.74    0.00      10/10          main [1]
[2]     53.1   18.74    0.00      10         float_test [2]
-----------------------------------------------
               16.57    0.00      10/10          main [1]
[3]     46.9   16.57    0.00      10         double_test [3]
-----------------------------------------------

我不确定编译器是否优化了我的一些代码,或者我是否做了足够的算术使其发挥作用。我觉得有点奇怪,double_test() 实际上比 float_test() 花费的时间更少。

我尝试切换函数调用的顺序,但结果仍然相同。有人可以向我解释一下吗?

最佳答案

在我的机器 (x86_64) 上,并排查看生成的代码:

double_test:                                  .. float_test:
  xorpd  %xmm0,%xmm0  // double n             --   xorps  %xmm0,%xmm0      // float n
  xor    %eax,%eax    // int i                ==   xor    %eax,%eax
loop:                                         .. loop:
                                              ++   unpcklps %xmm0,%xmm0    // Extend float n to...
                                              ++   cvtps2pd %xmm0,%xmm0    // ...double n
  add    $0x1,%eax     // ++i                 ==   add    $0x1,%eax
  addsd  %xmm2,%xmm0   // double n += DELTA   ==   addsd  %xmm2,%xmm0
  cvtsi2sd %eax,%xmm3  // (double)i           ==   cvtsi2sd %eax,%xmm3
                                              ++   unpcklpd %xmm0,%xmm0    // Reduce double n to...
                                              ++   cvtpd2ps %xmm0,%xmm0    // ...float n
  divsd  %xmm5,%xmm0   // double n /= 3.0     --   divss  %xmm4,%xmm0      // float n / 3.0
  ucomisd %xmm3,%xmm1  // (double)i cmp 1E7   ==   ucomisd %xmm3,%xmm1
  ja      ...loop...   // if (double)i < 1E7  ==   ja      ...loop...

显示了四个额外的指令,用于将向上更改为 double 并向下更改为 float ,以便添加 DELTA .

DELTA1E-8这隐含地double 。因此,添加完成 double 。当然,3.0也隐含地 double ,但我猜编译器发现 double 之间没有有效的区别和single在这种情况下。

定义DELTAF因为 1E-8f 消除了从 double 向上和向下的变化用于添加。

关于c - Beagle Bone Black 的 float 与 double 性能测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25185908/

相关文章:

c++ - 适用于 GCC 的优秀 C++ 分析器

python - 在 beaglebone black 上读取事件文件 C 和 python 时观察到的差异

c - 动态分配动态分配结构的数组?

c - 一个字节变量如何存储两个字节字符常量?

javascript - Firebug 分析问题 : "no activity to profile"

Python cProfile - 修饰函数模糊配置文件可视化

python - 读取输入数据到csv文件

audio - 我需要做什么才能在运行 debian 的 beaglebone 上设置 USB 音频小工具 i/o?

C:数学常数的枚举 VS #define?

c - 在 automake 中使用 LIBADD 时,libtool 链接不正确