cuda double问题

在gpu上要求解一个三次方程才c[3]ss*s+c[2]ss+c[1]*s+c[0]=0;
图片是方法
[attach]3288[/attach][attach]3289[/attach]
下面是对应代码

struct zuobiao
{
float x;
float y;
float z;
};

device host int reconstruction::SolveCubic(double c,zuobiao &s)
{
int i, num;
double sub;
double A, B, C;
double sq_A, p, q;
double cb_p, D;
double s_[3];
s_[0]=-1;
s_[1]=-1;
s_[2]=-1;
/* normal form: x^3 + Ax^2 + Bx + C = 0 /
A = c[ 2 ] / c[ 3 ];
B = c[ 1 ] / c[ 3 ];
C = c[ 0 ] / c[ 3 ];
/
substitute x = y - A/3 to eliminate quadric term:
x^3 +px + q = 0 /
sq_A = A * A;
p = 1.0/3 * (- 1.0/3 * sq_A + B);
q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C);
/
use Cardano’s formula /
cb_p = p * p * p;
D = q * q + cb_p;
if (IsZero(D))
{
if (IsZero(q)) /
one triple solution /
{
s_[0] = 0;
num = 1;
}
else /
one single and one double solution /
{
double u = cbrt(-q);
s_[0] = 2 * u;
s_[1] = - u;
num = 2;
}
}
else if (D < 0) /
Casus irreducibilis: three real solutions /
{
double phi = 1.0/3 * acos(-q / sqrt(-cb_p));
double t = 2 * sqrt(-p);
s_[0] = t * cos(phi);
s_[1] = - t * cos(phi + M_PI / 3);
s_[2] = - t * cos(phi - M_PI / 3);
num = 3;
}
else /
one real solution /
{
double sqrt_D = sqrt(D);
double u = cbrt(sqrt_D - q);
double v = - cbrt(sqrt_D + q);
s_[0] = u + v;
num = 1;
}
/
resubstitute /
sub = 1.0/3 * A;
for (i = 0; i < num; ++i)
s_[ i ] -= sub;
s.x=s_[0];
s.y=s_[1];
s.z=s_[2];
return num;
}
其中c[]是系数,s是解集
但这函数在GPU和在CPU上运行的结果差别很大,最后解出来s,再算c[3]s.xs.x
s.x+c[2]s.xs.x+c[1]*s.x+c[0]的值在CPU上运行可达到1e-7的精度,但在GPU上可能只有1e-3甚至1e-2.请问可以怎么解决,怎么提高GPU的进度呢?我在用GT630来算的

LZ您好:

GT630至少是fermi核心的,其浮点运算支持IEEE 754标准,并且具备FMA能力。

如果您没有使用fastmath设置的话,建议检查一下算法实现,看看有否考虑不周之处。

能造成浮点结果差别的地方一般有:算法实现错误,多线程算法导致浮点数运算顺序不同造成结果不同,硬件中间过程保留精度,硬件截断和圆整方式的差别等。如果差别较大,请优先考虑第一种可能。

大致建议如上,祝您调试顺利~

喔,好的,我再检查检查算法

嗯嗯,也欢迎您及时反馈结果,让大家共同进步。

还有两点需要稍微补充一下,如果CPU和GPU的结果有较小的差别,那么并不代表哪个精度更高,因为两者都只是一种顺序下的浮点运算结果,而浮点运算根据顺序不同,结果也会略有差异的。

以及,您在编译您的CUDA代码的时候,请选择合适的与您显卡计算能力版本一致的编译参数,以免出现其他问题。

祝您好运~