【问题标题】:In C programming, will a calculation be slower, if any variable in the expression is nan在C编程中,如果表达式中的任何变量是nan,计算会变慢吗
【发布时间】:2013-09-25 10:30:10
【问题描述】:

这完全是一个假设性问题。

在下面的代码中,我正在执行计算,它有一个变量 z ,作为分配“nan”的值。与正常的 z 值相比,主计算会更慢(如 z = 1.0)

float z = 0.0/0.0; // that means z is "nan"
float p = 50.0, q = 100.0, r = 150.0;
// main calculation Type 1
float c = ((x*100)+(y*100))/(x*100)+(y*100)+152*(p+q/r)+z;

这里是一个例子来展示正常z值的主要计算

float z = 1.0; // normal value for z
float p = 50.0, q = 100.0, r = 150.0;
// main calculation Type 2
float c = ((x*100)+(y*100))/(x*100)+(y*100)+152*(p+q/r)+z;

那么,哪一个更慢,Type 1 还是 Type 2?还是不会有时差? 在单次计算中,可能看不到时间差异,但是,如果我们收集数百万个这样的方程,时间结果会如何变化?

任何类型的想法、逻辑或信息都将受到赞赏。

注意:目前我不关心变量'c'的结果值;

【问题讨论】:

  • 你为什么不尝试计时?
  • 其实我得到了时差..但我想确定一下,是因为这个..有没有可能?
  • 如果我更假设地认为,带有 nan 的方程应该更快,因为它不必实际计算结果并且必须返回 'nan' 作为最终答案。
  • 为什么不看看拆解呢?
  • 您是否启用了优化?如果是这样,我希望 NAN 案例更快。

标签: c nan


【解决方案1】:

不会有任何区别。

在低级别,计算机只是分配值。不检查之前的内容。

计算的汇编代码必须相同。

如果您检查整个代码,则第一个程序必须较慢,因为您在其中进行了额外的计算。 (0.0/0.0)。

【讨论】:

  • 和我想的一样。
  • 这通常不是真的。 NaN 之类的值是特殊的,并且可以想象导致涉及它们的 CPU 操作不会通过快速路径执行,而是陷入慢得多的微编码实现。
  • 计算机不只是分配一个值,它还在做浮点运算,所以它必须解释这些值而不仅仅是复制它们。
  • 在其汇编代码中,当每次计算完成并且结果在 AC 中时,它只是调用 MVI。所以这个命令对以前的值不做任何事情。它只是立即移动 AC 值。你连汇编语言都懂吗?
【解决方案2】:

这取决于 CPU。没有 SSE 的旧 x86 英特尔芯片对 NAN 的处理非常糟糕(请参阅 http://www.cygnus-software.com/papers/x86andinfinity.html 了解 10 年前的分析。)但是,SSE2/3/4 没有遇到这个问题,我不相信 AMD 曾经做了。

如果你告诉你的编译器为了可能的兼容性而避免使用 SSE 指令,你很可能会在现代芯片上看到这个问题(但这肯定会减慢浮点数,不管 NaN 是什么,所以除非你必须这样做,否则不要这样做。)据我所知,这种兼容模式仍然是 x86 构建的 gcc 默认值。

我不知道 ARM 浮点单元;你必须测试。

我怀疑 NAN 已经不是十年前的问题了,但有足够多的人对那些时代的记忆模糊不清,这种偏见无疑会持续一段时间。

【讨论】:

  • 所以@rici 你是在暗示,有“可能”(或可能不会)时间可能会因为 nan 而有所不同??
  • @Vishwadeep:我不是在暗示。我在说。如果你有旧的 586 CPU,它们会因 NaN 而变慢。
  • 感谢您的信息.. 我会扩大范围
  • @rici 我已经编写了许多代码,其中在编译中启用 SSE 指令会减慢程序速度 - 有时会相当大。
【解决方案3】:

在某些 RISC 架构(例如 MIPS)上,浮点单元旨在尽可能快地处理常见情况。浮点单元在遇到 NaN 时会陷入陷阱,然后使用软件 IEEE 浮点仿真器处理剩余的计算。因此,在这样的架构上使用 NaN 进行计算会慢得多。 AFAIK 这不适用于 Intel x86 架构。

【讨论】:

    【解决方案4】:

    批判性思考确实让我挑战了我对 C 的理解。我认为最好的答案是进行实验。使用 time.h 保存每次计算前后的时钟时间并计算差值。

    #include<stdio.h>   
    #include<time.h> 
    clock_t t1, t2;
    float result;
    
    t1 = clock();
    //perform calculation1
    t2 = clock();
    printf("%f", result);
    
    t1 = clock();
    //perform calculation2
    t2 = clock();
    printf("%f", result);
    

    【讨论】:

    • clock 函数对此没有用处。它的分辨率太差了,你必须进行数百万次计算(并且避免让编译器决定全部优化它们,因为结果是未使用的或不变的),即使这样,它的实现也经常有错误。
    • 我的错!忘记了。
    猜你喜欢
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 2017-05-13
    • 2017-01-02
    • 2011-07-31
    相关资源
    最近更新 更多