GPU比CPU去掉了大量非计算单元(去掉L3, 降低缓存容量,精简控制器,降低分支能力和预测执行能力),增加了通用寄存器。其实CPU的浮点能力并不差,通常来说CPU的整数能力只是CPU浮点能力的2-5倍而已。 而GPU擅长浮点说的也不是很准确,其实GPU是擅长数值计算,不擅长应对分支和随机访存。通常GPU的int32能力并不会低于其float32能力。但是发挥GPU的计算能力需要批量化(向量化),连续访存,同时计算任务不要有太多分支。 之所以有 CPU 浮点能力差的说法,想有两个原因
另外需要指出的是,现在CPU主频通常比GPU高得多,所以CPU的功耗显得高了一点。如果比较CPU和GPU同频同功耗的性能,可能没大家想象的那么多。 CPU的浮点能力一点也不差,其实比GPU还高,因为它的主频高,Cache大。浮点运算本质上还是加减乘除运算。GPU浮点性能总体强大,是因为它的计算单元比CPU的大得多。CPU内部的浮点计算单元一般1-8个不等。而GPU内部则是几百上千个。 浮点是什么?是小数点的数字,这个没错但是关键区别在于它的格式。普通整数的表达方式很简单,就是二进制的同一个数字而已,1是1,2是10,3是11,4是100之类的。但是计算机里如何表示小数点?所谓浮点最重要的区别就是它是用科学计数法的,一个浮点数字被分为两半,其中一半记录一个数字,另一半记录10的多少次方。比如1.56424可以写成: 156424乘以10的-5次方 这样就把一个小数变成了两个整数,但是其中一个是负数,电脑怎么表示负数?这个也简单,比如说总共只有4位数,可以表达0-9999,可以把它分为两半,定义其中4999表示0,4998表示-1,5000表示+1等等。这样就可以表达-4999到+4999了。 还是刚才的小数1.56424,就可以把它写成两个整数: 156424,4994 这就是电脑里的浮点数。很明显当要相加这样的两个数字,程序和直接相加两个整数是完全不同的,因为其中一部分是次方数,次方数不同的两个数字不能相加,相同的相加出来的结果也可能影响次方数等等问题。当然可以写一个软件进行各种换算让cpu的基本整数运算电路来算浮点,但是这样很慢。更好的办法是直接在处理器里设置算浮点的电路,这就是现代cpu里的fpu。 再看看刚才举例的这个浮点数: 156424,4994 由于CPU的电路设计是基于位宽的,就是说这个数据有多少位数字,比如上面这个就是12位,实际上写浮点数字的时候是有固定长度的。比如这个数字代表的小数是1.56424,在同样格式的情况下是无法表达1.56424739的,多余出来的位数只能直接丢掉。这也就是说浮点数据不是完全准确的,而是近似值 如果用基本的浮点指令去计算10除以3再乘以3,它会告诉是9.99999999。这就是因为浮点数据的有损特性。要缓解这个精度问题,只能提高位数,比如12位的浮点格式给改成20位。但是要一次计算20位长度的浮点,就需要更宽,更复杂的电路。实际使用的单精度浮点是32位,双精度是64位。 英特尔的cpu计算浮点的时候内部精度是80位,输出输入还是64位。显卡很多都是单精度32位的,就算支持64位的话速度一般会尿崩。专业计算卡现在一般都是64位。所以说第一个问题就是复杂程度,cpu的fpu率先支持了更高宽度的数据,电路更复杂。而显卡一直以来都是在用单精度浮点,很多根本没法执行双精度运算。 第二个问题就是CPU的fpu是和逻辑单元同步的,这样可以保证编程方面的兼容性,因为以前的机器一直是这么搞的,老传统了。核心数量和频率都是同步的,每个fpu必须配对全套的逻辑,解码单元等等。所以说cpu只能几个核心。但是既然反正核心就那么几个,就可以把它做得异常强大,支持各种最宽的数据格式,可以用更少的步骤做三角函数,除法,开方之类的计算。 而相比之下显卡基本就是大批大批的小型FPU,其他的东西能少就少。如果只做一道浮点运算,其实是cpu更快,而且可以块非常多。但问题是通常来说浮点运算都是大批量的作,而且互相之间没有关联,一道题的结果和下一题的结果很少有关联。这种情况下大批大批的小型fpu就有优势了。 |
|
来自: 昵称11935121 > 《未命名》