cuda浮点精度

sma*_*ato 1 c c++ cuda

有人可以对此发表评论,

我想做一个矢量点积.我的浮点矢量是[2080:2131]和[2112:2163],每个都包含52个元素.

a[52] = {2080 2081 2082 ... ... 2129 2130 2131};
b[52] = {2112 2113 2114 ... ... 2161 2162 2163};

for (int i = 0; i < 52; i++)
{
    sum += a[i]*b[i];
}
Run Code Online (Sandbox Code Playgroud)

我的内核的全长(52元素)的结果总和为234038032,而matlab的结果为234038038.对于产品的1到9元素总和,我的内核结果与matlab结果一致.对于10个元素的总和,它偏离1并逐渐增加.结果是可重复的.我检查了所有元素,发现没有问题.

Tom*_*Tom 11

由于向量是浮动的,因此您遇到舍入错误.Matlab将以更高的精度(双倍)存储所有内容,因此不会那么早地看到舍入误差.

你可能想看看大卫戈德伯格的每个计算机科学家应该知道什么关于浮点 - 非常宝贵的阅读.

C++中的简单演示(即与CUDA无关):

#include <iostream>

int main(void)
{
  float a[52];
  float b[52];
  double c[52];
  double d[52];

  for (int i = 0 ; i < 52 ; i++)
  {
    a[i] = (float)(2080 + i);
    b[i] = (float)(2112 + i);
    c[i] = (double)(2080 + i);
    d[i] = (double)(2112 + i);
  }

  float fsum = 0.0f;
  double dsum = 0.0;
  for (int i = 0 ; i < 52 ; i++)
  {
    fsum += a[i]*b[i];
    dsum += c[i]*d[i];
  }

  std::cout.precision(20);
  std::cout << fsum << " " << dsum << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

运行这个,你得到:

234038032 234038038
Run Code Online (Sandbox Code Playgroud)

那么你能做些什么呢?你可以进入几个方向......

  • 使用更高的精度:这将影响性能,并非所有设备都支持双精度.它也只是推迟问题而不是修复它,所以我不推荐它!
  • 进行基于树的缩减:您可以组合vectorAdd和reduction SDK示例中的技术.
  • 使用推力:非常直截了当.