请考虑以下C ++代码段:(Visual Studio 2015)
第一个区块
const int size = 500000000;
int sum =0;
int *num1 = new int[size];//initialized between 1-250
int *num2 = new int[size];//initialized between 1-250
for (int i = 0; i < size; i++)
{
sum +=(num1[i] / num2[i]);
}
第二个区块
const int size = 500000000;
int sum =0;
float *num1 = new float [size]; //initialized between 1-250
float *num2 = new float [size]; //initialized between 1-250
for (int i = 0; i < size; i++)
{
sum +=(num1[i] / num2[i]);
}
我希望第一个块运行更快,因为它是整数运算。但是,尽管第二块是浮点运算,但它的运行速度要快得多。这是我的基准测试结果: 师:
Type Time
uint8 879.5ms
uint16 885.284ms
int 982.195ms
float 654.654ms
浮点乘法比整数乘法更快。 这是我基准测试的结果:
乘法:
Type Time
uint8 166.339ms
uint16 524.045ms
int 432.041ms
float 402.109ms
我的系统规格:CPU核心i7-7700,Ram 64GB,Visual Studio 2015
答案 0 :(得分:6)
由于floating point number representation中的指数部分,浮点数除法比整数除法快。用一个简单的减法将一个指数除以另一个。
int32_t
除法需要对31位数字进行快速除法,而float
除法则需要对24位尾数进行快速除法(隐含尾数中的前导且不存储在浮点数中)并更快地减去8位指数。
查看excellent detailed explanation how division is performed in CPU。
值得一提的是SSE和AVX指令仅提供浮点除法,而没有整数除法。 SSE指令/整数可以轻松使您的float
计算速度提高三倍。
例如,如果您查看Agner Fog's instruction tables,对于Skylake,则32位整数除法的等待时间为26个CPU周期,而SSE标量浮点除法的等待时间为11个CPU周期(令人惊讶的是, ,则需要花费相同的时间来划分四个打包的浮点数。
还要注意,在C和C ++中,没有对短于int
的数字进行除法,因此首先将uint8_t
和uint16_t
提升为int
,然后除法的int
发生了。 uint8_t
的划分看起来比int
快,因为转换为int
时它设置的位较少,这导致划分完成得更快。