为什么浮点除法比c ++中的整数除法更快?

问题描述 投票:1回答:1

考虑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

performance c++11 floating-point int division
1个回答
6
投票

由于floating point number representation中的指数部分,浮点数除法比整数除法快。为了将一个指数除以另一个指数,使用普通减法。

int32_t除法需要快速划分31位数字,而float除法需要快速划分24位尾数(尾数中的前导符号暗示并且不存储在浮点数中)和8位指数的快速减法。

看到excellent detailed explanation how division is performed in CPU

值得一提的是SSE和AVX指令只提供浮点除法,但没有整数除法。 SSE指令/ intrinsincs可用于轻松地将float计算的速度提高四倍。

例如,如果你看看用于Skylake的Agner Fog's instruction tables,32位整数除法的延迟是26个CPU周期,而SSE标量浮点除法的延迟是11个CPU周期(并且,令人惊讶的是,它需要相同的时间到划分四个包装的浮子)。

还要注意,在C和C ++中,没有对int更短的数字进行划分,因此uint8_tuint16_t首先被提升为int然后ints的划分发生。 uint8_t除法看起来比int更快,因为它在转换为int时设置的位数更少,这使得除法更快完成。

© www.soinside.com 2019 - 2024. All rights reserved.