私は、異なる表現の効果を比較するベンチマークプログラムを実装しました。
私はyを倍精度で計算してから、異なる精度の単精度を使ってyを計算しました。ここ
は、試験した式である:
inline double getYDbl(double x, double x0, double y0, double x1, double y1)
{
double const t = (x - x0)/(x1 - x0);
return y0 + t*(y1 - y0);
}
inline float getYFlt1(float x, float x0, float y0, float x1, float y1)
{
double const t = (x - x0)/(x1 - x0);
return y0 + t*(y1 - y0);
}
inline float getYFlt2(float x, float x0, float y0, float x1, float y1)
{
double const t = (x - x0)*(y1 - y0);
return y0 + t/(x1 - x0);
}
inline float getYFlt3(float x, float x0, float y0, float x1, float y1)
{
double const t = (y1 - y0)/(x1 - x0);
return y0 + t*(x - x0);
}
inline float getYFlt4(float x, float x0, float y0, float x1, float y1)
{
double const t = (x1 - x0)/(y1 - y0);
return y0 + (x - x0)/t;
}
Iは、倍精度の結果と単精度結果との差の平均値とSTDDEVを計算しました。
この結果、平均で1000個以上のランダム値セットが存在しないことになります。私はiccコンパイラを使用し、最適化せずにg ++を使用しました。
私は、偽の値をフィルタリングするためにisnan()関数を使用しなければならないことに注意してください。私は、これらの結果が差異または部門のアンダーフローに起因すると考えています。
コンパイラが式を再配置するかどうかわかりません。とにかく、このテストからの結論は、式の上記の再編成が計算精度に影響を与えないということである。エラーは(平均して)同じままです。
sinやcosのような三角関数を使用できますか? AFAIK、より新しいすべてのGPUはそれらを単一の命令として持っているので、速くなければなりません。 –
xがx0とx1の間にある場合、大きなエラーはありません。 tを計算するとき、同じ大きさの値x-x0、x1-x0を扱います。 –