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

时间:2014-10-06 02:13:01

标签: c linux performance floating-point 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;
    }
}

对于师(/):

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

对于时间测量,使用以下代码。 使用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);
}

结果,加法(+)和除法(/)的处理时间都在2500纳秒左右。

一般来说,我认为这种划分比添加更贵,但在这种情况下差别不大。

我想知道

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

1 个答案:

答案 0 :(得分:6)

您的代码可能存在一些问题:

  • 您没有向您的函数传递任何参数,因此优化可能会预先计算其结果。
  • 调用计时功能和调用函数会产生很大的开销,因此不会看到减速。
  • 您使用的计时器的粒度(尝试granularity test
  • 您使用浮点数作为结果但是您正在执行双打中的所有操作 - 3.14是双倍的,3.14f是浮动的。
  • 100次循环太少,看不到任何合理的,尝试增加循环次数,以达到至少1秒的执行时间。
  • 您可以尝试取消这些功能以查看现实情况。
  • 您是否正在使用硬件浮点支持进行编译?