c - 32位浮点除法并没有我想象的那么慢

标签 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
  • 用于搜索有关此类优化的更多信息的关键字
  • (如果有)检查处理时间的代码中的一些错误(例如,避免循环内的自动优化等)

最佳答案

您的代码可能存在几个问题:

  • 您没有向函数传递任何参数,因此优化可能会预先计算其结果。
  • 调用计时函数和调用您的函数的开销很大,因此速度下降是不可见的。
  • 您使用的计时器的粒度(尝试 granularity test)
  • 您正在使用 float 作为结果,但您正在以 double 执行所有操作 - 3.14 是 double ,3.14f 是 float 。
  • 100 次循环太少,看不到任何合理的地方,请尝试增加循环数以达到至少 1 秒的执行时间。
  • 您可以尝试禁用这些功能,看看实际情况如何。
  • 您是否使用硬件浮点支持对其进行编译?

关于c - 32位浮点除法并没有我想象的那么慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26209229/

相关文章:

c - APUE<2nd> 11.4,先发信号或先解锁

python - UDP python 到 c 打包的二进制数据 - struct.pack ('<ff' ,

c - 分解预先格式化的字符串

linux - 如何在 Makefile 中捕获退出 (ctrl+c) 信号?

SQL - 最快的间隔查找

c - header 中的共享 C 常量

linux - 如何判断进程是否正在运行?

linux - 使用 rename 命令重命名 .bmp 文件

python - 为什么 numpy.where 比替代方案快得多

mysql - 带排序的 SQL 查询