32位浮动分区并不像我预期的那么慢

sev*_*ine 0 c linux floating-point performance arm

我的环境:

  • Xilinx Zynq(基于ARM Cortex A9)
  • PetaLinux V2014.2

我正在使用PetaLinux在Zynq上开发Linux应用程序.

我目前的问题是四个算术运算的处理时间(+/ - /*/div).

clock_gettime()使用以下代码计算处理时间.

添加(+):

static void funcToBeTimed_floatAdd(void)
{
    int idx;
    float fval = 0.0;
    for(idx=0; idx<100; idx++) {
        fval = fval + 3.14;
    }
}
Run Code Online (Sandbox Code Playgroud)

对于部门(/):

static void funcToBeTimed_floatDiv(void)
{
    int idx;
    float fval = 314159000.00;
    for(idx=0; idx<100; idx++) {
        fval = fval / 1.001;
    }
}
Run Code Online (Sandbox Code Playgroud)

对于时间测量,使用以下代码.在procNo使用设置main(int argc, char *argv[])

static void disp_elapsed(int procNo)
{
    struct timespec tp1, tp2;
    long dsec, dnsec;

    /***/
    switch(procNo) {
    case 0:
        printf("add\n");
        clock_gettime(CLOCK_REALTIME, &tp1);
        funcToBeTimed_floatAdd();
        clock_gettime(CLOCK_REALTIME, &tp2);
        break;
    case 1:
        printf("multi\n");
        clock_gettime(CLOCK_REALTIME, &tp1);
        funcToBeTimed_floatMulti();
        clock_gettime(CLOCK_REALTIME, &tp2);
        break;
    default:
        printf("div\n");
        clock_gettime(CLOCK_REALTIME, &tp1);
        funcToBeTimed_floatDiv();
        clock_gettime(CLOCK_REALTIME, &tp2);
        break;
    }

    dsec = tp2.tv_sec - tp1.tv_sec;
    dnsec = tp2.tv_nsec - tp1.tv_nsec;
    if (dnsec < 0) {
        dsec--;
        dnsec += 1000000000L;
    }

    printf("Epalsed (nsec) = %ld\n", dnsec);
}
Run Code Online (Sandbox Code Playgroud)

结果,加法(+)和除法(/)的处理时间均为2500纳秒左右.

一般来说,这种划分比添加成本更高,我想,但在这种情况下差别不大.

我想知道

  • 什么样的优化适用于ARM
  • 用于搜索有关此类优化的更多信息的关键字
  • (如果有的话)代码中的一些错误来检查处理时间(例如,避免内部循环中的自动优化等)

j12*_*567 6

您的代码可能有几个问题:

  • 您没有向函数传递任何参数,因此优化可能会预先计算其结果.
  • 调用计时功能和调用函数会产生很大的开销,因此减慢速度是不可见的.
  • 您使用的计时器的粒度(尝试粒度测试)
  • 你使用浮点数作为结果,但你在双打中执行所有操作 - 3.14是double,3.14f是浮点数.
  • 100个周期太少,看不到任何合理的,尝试增加周期数以达到至少1秒的执行时间.
  • 你可以尝试解除这些功能,看看现实是什么.
  • 您是否正在使用硬件浮点支持进行编译?