jac*_*ace 10 c performance time
我在使用小精度浮点数执行算术运算时检测到了不寻常的计算时间.以下简单代码表现出此行为:
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
const int MAX_ITER = 100000000;
int main(int argc, char *argv[]){
double x = 1.0, y;
int i;
clock_t t1, t2;
scanf("%lf", &y);
t1 = clock();
for (i = 0; i < MAX_ITER; i++)
x *= y;
t2 = clock();
printf("x = %lf\n", x);
printf("Time: %.5lfsegs\n", ((double) (t2 - t1)) / CLOCKS_PER_SEC);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以下是该程序的两个不同运行:
y = 0.5
x = 0.000000
时间:1.32000秒
y = 0.9
x = 0.000000
时间:19.99000秒
我正在使用具有以下规格的笔记本电脑来测试代码:
有人可以详细解释为什么会出现这种情况吗?我知道,当y = 0.9时,x值比y = 0.5更慢,所以我怀疑问题与此直接相关.
Dav*_*nco 10
非正规(或相当低于正常)数字通常会受到性能影响.0根据你的第二个例子,慢慢收敛会产生更多的次正规.在这里和这里阅读更多.对于更严肃的阅读,请查看经常引用的(并且非常密集)每个计算机科学家应该知道的关于浮点运算的内容.
来自第二个来源:
在IEEE-754下,浮点数用二进制表示为:
Number = signbit \* mantissa \* 2exponent有可能有多种表示相同数字的方式,使用小数作为示例,数字0.1可以表示为1*10-1或0.1*100或甚至0.01*10.标准规定数字始终存储在第一位作为一个.在十进制中,对应于1*10-1示例.
现在假设可以表示的最低指数是-100.因此,可以用正常形式表示的最小数字是1*10-100.但是,如果我们放宽前导位为1的约束,那么我们实际上可以在同一空间中表示较小的数字.以十进制为例,我们可以表示0.1*10-100.这称为次正规数.具有次正规数的目的是平滑最小正常数和零之间的差距.
认识到正常数字的精度低于正常数字是非常重要的.事实上,他们以较小的尺寸交易精度较低.因此,使用次正规数的计算与正常数的计算不具有相同的精度.因此,对次正规数进行重要计算的应用程序可能值得研究,以确定重新缩放(即将数字乘以某个缩放因子)将产生更少的次正规,并且更准确的结果.
我正在考虑自己解释它,但上面的解释是非常好的书面和简洁.