cpu不像人类?0 + 0不比10E12 + 9E15容易

本文关键字:10E12 9E15 容易 不比 人类 cpu | 更新日期: 2023-09-27 18:01:22

我的孩子昨天问了我一个有趣的问题:

爸爸,电脑会像我一样在做大数字的加法/乘法时遇到困难吗?需要更长的时间吗?

我笑着回答说当然不是,电脑处理任何数字都一样快,它们就是聪明。

后来,我开始思考这个问题,并问自己……我说的对吗?我用双精度和整数测试了一些场景,是的,数字的大小似乎对CPU执行操作所需的时间没有任何影响(是的,我很无聊)。

高度复杂的测试实现如下:

static void Main(string[] args)
{
   Test(1, 0); //JIT test method
   var elapsed = Test(int.MaxValue, 0);
   Console.WriteLine("Testing with 0: {0} ms", elapsed);
   elapsed = Test(int.MaxValue, 1);
   Console.WriteLine("Testing with 1: {0} ms", elapsed);
   elapsed = Test(int.MaxValue, 1000000);
   Console.WriteLine("Testing with 10E6: {0} ms", elapsed);
   elapsed = Test(int.MaxValue, long.MaxValue / 2);
   Console.WriteLine("Testing with MaxValue/2: {0} ms", elapsed);
   Console.ReadKey();
}
private static long Test(int repetitions, long testedValue)
{
   var stopwatch = new Stopwatch();
   stopwatch.Start();
   for (int i=0; i<repetitions; ++i)
   {
       var dummy = testedValue + testedValue;
   }
   stopwatch.Stop();
   return stopwatch.ElapsedMilliseconds;
}
但是,这个问题一直在我的脑海里挥之不去。我不是一个真正的专家,算术是如何在现代CPU中执行的,所以我有点兴趣知道为什么没有区别。

cpu不像人类?0 + 0不比10E12 + 9E15容易

计算机加/乘有问题吗

不是最好的例子,这些操作可以由处理器中的逻辑电路执行。专用硬件,它只需要一个cpu周期,尽可能快。然而,也有一些悲观的情况,它们发生在操作数不"规则"的情况下。当一个数字是不正常的,太小而不能作为常规浮点数存储,或者当它是NaN,非数字时,就会发生这种情况。

在英特尔手册中,

被列为"FP Assist",处理器逻辑进入,不再将其留给硬件加法器/乘法器,而是执行微码。这听起来很像,一个嵌入处理器本身的小程序。非常昂贵,很容易就需要100次循环。你会在这篇文章中找到一个很好的例子。

对你的孩子来说,更直观的是除法,它就像长除法在纸上一样,在硬件上一样费力,需要迭代的方法。通常需要10到24个周期,多长时间取决于操作数的值。值和周期数之间的确切依赖关系是模糊的,处理器供应商将这类实现细节视为商业机密。你可能需要尝试一堆随机数来观察效果

一般来说,硬件支持固定精度。例如,32位处理器通常支持整数32乘32乘法(至少要得到低结果)和32位加法。在延迟方面(即从计算开始到完成计算的时间),大多数处理器对于双精度浮点的延迟与单精度相同,但是具有SIMD操作的可以并行执行两倍的单精度操作。

在32位处理器上,64位整数的加法通常会使延迟至少增加一倍,吞吐量减少一半。(有些指令集没有进位加法,所以多精度加法是通过加法、小于的检查(如果总和小于任何一个源操作数,则发生进位)和进位的单独加法来合成的。

爸爸,电脑会像我一样在做大数字的加法/乘法时遇到困难吗?需要更长的时间吗?

不,当然不是。

两个32位整数的加法总是占用完全相同的时间,无论内容如何。事实上,这是一个完全的机械操作。CPU有一个时钟,在每个时钟周期它做同样的事情——加载命令,执行命令,等等——完全固执和愚蠢的;)

就像老工厂的皮带一样,以相同的恒定速度运行,每个工人总是做同样的事情,比如转动4个螺丝…(而且,除了人类,机器永远不会累)。