Поскольку векторы являются плавающими, у вас возникают ошибки округления.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;
}
Запустите это и вы получите:
234038032 234038038
Так что вы можете с этим поделать?Вы можете пойти в нескольких направлениях ...
- Используйте более высокую точность: это повлияет на производительность, и не все устройства поддерживают двойную точность.Это также просто откладывает проблему, а не исправляет ее, поэтому я бы не рекомендовал ее!
- Делать редукцию на основе дерева: вы можете комбинировать приемы в выборках vectorAdd и Reduction SDK.
- Использовать Тяга : очень прямолинейная.