为什么在C ++中浮点除法比整数除法快?

Moh*_*esh 1 floating-point int performance division c++11

考虑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]);
}
Run Code Online (Sandbox Code Playgroud)

第二块

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]);
}
Run Code Online (Sandbox Code Playgroud)

我期望第一个块运行更快,因为它是整数运算。但是,尽管第二块是浮点运算,但它的运行速度要快得多。这是我的基准测试结果:部门:

Type    Time
uint8   879.5ms
uint16  885.284ms
int     982.195ms
float   654.654ms
Run Code Online (Sandbox Code Playgroud)

浮点乘法比整数乘法快。这是我的基准测试结果:

乘法:

Type    Time
uint8   166.339ms
uint16  524.045ms
int     432.041ms
float   402.109ms
Run Code Online (Sandbox Code Playgroud)

我的系统规格:CPU核心i7-7700,Ram 64GB,Visual Studio 2015

Max*_*kin 6

由于浮点数表示中的指数部分,浮点数的划分比整数除法快。用一个简单的减法将一个指数除以另一个。

int32_t除法要求对31位数字进行float快速除法,而除法要求对24位尾数进行快速除法(隐含尾数中的前导且不存储在浮点数中),并且需要对8位指数进行更快的减法。

请参阅出色的详细说明,以了解如何在CPU中执行除法

值得一提的是,SSE和AVX指令仅提供浮点除法,而不提供整数除法。SSE指令/ intrinsincs可以float轻松使计算速度提高四倍。

例如,如果查看Agner Fog的指令表,对于Skylake,则32位整数除法的等待时间为26个CPU周期,而SSE标量浮点除法的等待时间为11个CPU周期(令人惊讶的是,它花费了同时划分四个包装好的花车)。

还要注意,在C和C ++中的数字较短,没有分工int,使uint8_tuint16_t首先被晋升为int,然后分工int小号发生。uint8_t除法看起来比int因为除法时转换后设置的位少int而导致除法更快完成,因此它看起来更快。

  • 虽然 int 下没有除法,但在 as-if 下,只要结果相同,编译器就可以使用 sub-int 除法自由进行除法。 (2认同)