【问题标题】:Is there any benefit of not using double on a 64bit (and using, say, float instead) processor?在 64 位(例如,使用浮点数)处理器上不使用 double 有什么好处吗?
【发布时间】:2015-09-01 17:46:20
【问题描述】:

我总是使用 double 来进行计算,但 double 提供的准确度比我需要的要高得多(或者说是有道理的,因为我所做的大多数计算都是以近似值开始的)。

但由于处理器已经是 64 位,我不认为使用位数较少的类型会有任何好处。

我是对还是错,我将如何优化速度(我知道较小的类型会更节省内存)

这是测试

#include <cmath>
#include <ctime>
#include <cstdio>

template<typename T>
void creatematrix(int m,int n, T **&M){
    M = new T*[m];
    T *M_data = new T[m*n];

    for(int i=0; i< m; ++i) 
    {
        M[i] = M_data + i * n;
    }
}

void main(){
    clock_t start,end;
    double diffs;
    const int N = 4096;
    const int rep =8;

    float **m1,**m2;
    creatematrix(N,N,m1);creatematrix(N,N,m2);

    start=clock();
    for(int k = 0;k<rep;k++){
        for(int i = 0;i<N;i++){
            for(int j =0;j<N;j++)
                m1[i][j]=sqrt(m1[i][j]*m2[i][j]+0.1586);
        }
    }
    end = clock();
    diffs = (end - start)/(double)CLOCKS_PER_SEC;
    printf("time = %lf\n",diffs);


    delete[] m1[0];
    delete[] m1;

    delete[] m2[0];
    delete[] m2;

    getchar();
}

double 和 float 没有时间差,但是不使用平方根时,float 的速度是原来的两倍。

【问题讨论】:

  • /sqrt 之类的操作对于 double 而言通常比 float 慢得多 - 检查您对目标 CPU 感兴趣的操作的吞吐量/延迟。
  • 当你使用它们很多时,缓存利用率会更好。矢量化代码也可以表现得更好。只有在您知道自己在做什么时才对数学模型进行修补,这很少是随意的选择。
  • @PaulR 我更新了我的帖子并进行了测试。 double 和 float 几乎没有时差。
  • 我刚发现sqrt的float版本是sqrtf,这导致时间减少了20%
  • 如果你在循环中加入除法运算,你可能会看到更大的差异,例如将+0.1586 更改为/0.1586(或/0.1586f 用于float 版本)。

标签: c++ floating-point 64-bit double


【解决方案1】:

有几种方法可以更快:

  • 更快的 I/O:只有一半的位可以在磁盘/内存/缓存/寄存器之间移动
  • 通常,唯一较慢的运算是平方根和除法。例如,在 Haswell 上,DIVSS(浮点除法)需要 7 个时钟周期,而DIVSD(双除法)需要 8-14(来源:Agner Fog's tables)。
  • 如果您可以利用 SIMD 指令,则每条指令可以处理两倍的指令(即在 128 位 SSE 寄存器中,您可以对 4 个浮点数进行操作,但只能对 2 个双精度数进行操作)。
  • 特殊函数(logsin)可以使用低阶多项式:例如log 的 openlibm 实现使用 7 次多项式,而 logf 只需要 4 次。
  • 如果您需要更高的中间精度,您可以简单地将float 提升为double,而对于double,您需要software double-double,或者更慢的long double

请注意,这些点也适用于 32 位架构:与整数不同,格式的大小与您的架构相匹配并没有什么特别之处,即在大多数机器上,双精度数与浮点数一样“原生”。

【讨论】:

  • float 的速度大约是原来的两倍
  • 但仅适用于大型数组(例如,对于 128x128 矩阵,double 与 float 没有区别,但对于 8192x8192 矩阵,float 速度要快一倍)
  • 大矩阵运算是利用上述 (i) 和 (iii) 点的理想情况(大量 I/O,易于使用的 SIMD)。
猜你喜欢
  • 1970-01-01
  • 2011-04-24
  • 2010-10-11
  • 2012-07-17
  • 2011-06-01
  • 2014-10-26
  • 1970-01-01
  • 2018-01-29
相关资源
最近更新 更多