在现代硬件上,浮点数和整数计算的区别

14 浏览
0 Comments

在现代硬件上,浮点数和整数计算的区别

我正在C++中进行一些性能关键的工作,而我们目前使用整数计算来解决本质上是浮点数的问题,因为“这样更快”。这导致了很多烦人的问题,并增加了很多烦人的代码。\n现在,我记得在大约386时代,有关浮点计算非常慢的文章,那个时候可能有一个可选的协处理器。但现在,由于CPU变得更加复杂和强大,无论是进行浮点还是整数计算,在“速度”上都没有差别了,特别是实际计算时间与引起流水线停顿或从主存中获取某些内容相比微不足道。\n我知道正确的答案是在目标硬件上进行基准测试,那么有什么好方法可以测试这个问题呢?我写了两个微小的C++程序,并使用Linux上的“time”命令比较它们的运行时间,但实际运行时间太过变化(我运行在一个虚拟服务器上也没有帮助)。除了花费整天运行数百个基准测试、制作图表等等之外,我还能做些什么来得到一个合理的速度测试呢?有什么想法或想法吗?我完全错了吗?\n我使用的两个程序如下,它们并不完全相同:\n

#include 
#include 
#include 
#include 
int main( int argc, char** argv )
{
    int accum = 0;
    srand( time( NULL ) );
    for( unsigned int i = 0; i < 100000000; ++i )
    {
        accum += rand( ) % 365;
    }
    std::cout << accum << std::endl;
    return 0;
}

\n程序2:\n

#include 
#include 
#include 
#include 
int main( int argc, char** argv )
{
    float accum = 0;
    srand( time( NULL ) );
    for( unsigned int i = 0; i < 100000000; ++i )
    {
        accum += (float)( rand( ) % 365 );
    }
    std::cout << accum << std::endl;
    return 0;
}

\n编辑:我关心的平台是在桌面Linux和Windows机器上运行的常规x86或x86-64。\n编辑2(从下面的评论中粘贴):我们目前有一个庞大的代码库。实际上,我遇到了一个普遍观点,即“不要使用浮点数,因为整数计算更快”,我正在寻找一种方法(如果这是真的)来证明这个普遍的观点是错误的。我意识到在没有完成所有工作并进行后续分析的情况下,准确预测结果是不可能的。\n不管怎样,感谢你们所有优秀的答案和帮助。欢迎添加任何其他内容:)

0
0 Comments

浮点运算与整数运算在现代硬件上的比较

在现代计算机硬件上,浮点运算和整数运算的性能是一个重要的问题。通过对不同处理器的测试可以看出,不同处理器的性能差异很大。下面是一些使用gnu编译器的测试结果,可以看出不同处理器上不同类型的运算的性能表现:

Intel i7 4700MQ xenial

short add: 0.822491

short sub: 0.832757

short mul: 1.007533

short div: 3.459642

long add: 0.824088

long sub: 0.867495

long mul: 1.017164

long div: 5.662498

long long add: 0.873705

long long sub: 0.873177

long long mul: 1.019648

long long div: 5.657374

float add: 1.137084

float sub: 1.140690

float mul: 1.410767

float div: 2.093982

double add: 1.139156

double sub: 1.146221

double mul: 1.405541

double div: 2.093173

从上面的测试结果中可以看出,不同类型的运算在不同处理器上的性能表现存在很大的差异。例如,在Intel i7 4700MQ处理器上,浮点加法的性能比整数加法的性能要差。同样的,不同处理器上的性能差异也很大,例如在AMD Opteron(tm) Processor 4122处理器上,整数除法的性能要比浮点除法的性能差很多。

造成这种差异的原因可能有很多,例如不同处理器的架构设计、指令集支持等因素。解决这个问题的方法可能包括优化编译器的代码生成策略、使用SIMD指令集进行向量化优化等。

总之,浮点运算和整数运算在现代硬件上的性能差异是一个复杂的问题,不同处理器上的性能差异很大。通过对不同处理器进行测试和优化,可以提高程序的性能。

0
0 Comments

在现代硬件上,浮点数和整数计算的性能存在很多变量,所以对于这个问题的答案只能是“这要看情况”。不同的处理器(即使是同一家如x86)之间的性能差异很大,因为不同的处理器有不同的“流水线”长度。此外,一些操作通常非常简单(例如加法),并且在处理器中有一个加速路径,而其他操作(例如除法)则需要更长的时间。

另一个重要变量是数据所在的位置。如果只有几个值需要相加,那么所有数据都可以存在缓存中,可以快速发送到CPU。一个非常非常慢的浮点运算,如果数据已经在缓存中,将比一个整数运算快得多,因为整数需要从系统内存中复制。

我猜你问这个问题是因为你正在开发一个性能关键的应用程序。如果你正在开发针对x86架构的应用程序,并且需要额外的性能,你可能想考虑使用SSE扩展。这可以极大地加快单精度浮点运算的速度,因为可以同时对多个数据执行相同的操作,而且SSE操作有一个独立的寄存器备用库。(我注意到你在第二个例子中使用了“float”而不是“double”,这让我觉得你在使用单精度数学)。

*注意:使用旧的MMX指令实际上会减慢程序的速度,因为那些旧指令实际上使用与FPU相同的寄存器,使得无法同时使用FPU和MMX。

而且在一些处理器上,浮点数运算可能比整数运算更快。Alpha处理器有一个浮点除法指令,但没有整数除法指令,所以整数除法必须在软件中完成。

SSE也会加速双精度浮点运算吗?对不起,我对SSE不太熟悉。

-litb:SSE2(x86-64的基准)具有打包的双精度浮点数。每个寄存器只有两个64位的双精度数,所以在能够向量化的代码中,潜在的加速比对于float来说较小。标量的float和double在x86-64上使用XMM寄存器,而遗留的x87仅用于long double。(因此@Dan:不,MMX寄存器不会与普通的FPU寄存器冲突,因为在x86-64上普通的FPU就是SSE单元。如果你可以进行整数SIMD计算,那么MMX将没有意义,因为你希望使用16字节的xmm0..15而不是8字节的mm0..7,而且现代CPU的MMX吞吐量更差。)

但是MMX和SSE*/AVX2整数指令会竞争相同的执行单元,所以同时使用它们几乎从来不会有用。只需使用更宽的XMM / YMM版本来完成更多的工作。同时使用SIMD整数和浮点数会竞争相同的寄存器,但是x86-64有16个寄存器。但是总吞吐量限制意味着通过同时使用整数和浮点执行单元来完成两倍的工作是不可能的。

0
0 Comments

现代硬件上的浮点运算和整数运算存在差异,这是由于CPU架构和硬件设计的不同引起的。具体来说,不同的CPU架构可能具有不同的ALU(算术逻辑单元)/FPU(浮点运算单元)性能,以及每个核心中可用的ALU/ FPU数量的差异。此外,浮点运算和整数运算的性能也受到数值大小的影响。一般来说,乘法比除法要快得多。

为了测试浮点运算和整数运算的性能差异,作者使用了一个简单的基准测试程序。该程序对一系列的运算进行循环操作,并记录了每种运算所需的时间。测试结果显示,不同的运算在不同的硬件上的性能表现差异很大。

然而,需要注意的是,这个基准测试程序并没有考虑到数据并行性,因为所有的操作都是使用相同的累加器进行的。在现代的Intel设计中,除法的流水线化程度非常低,而乘法可以每个周期发射一个指令。此外,不同的编译器对浮点运算和整数运算的优化程度也有所不同。

总结起来,浮点运算和整数运算在现代硬件上的性能差异是由CPU架构、硬件设计以及编译器优化等多个因素共同影响的结果。为了获取准确的性能数据,需要对特定的硬件和编译器进行详细的测试和分析。

0