私はいくつかのタイミングテストを行い、このようないくつかの記事(最後のコメント)も読みました。リリースビルドでは、float値とdouble値の処理時間は同じです。
これはどのようにして可能ですか?floatがdouble値と比較して精度が低く、小さい場合、CLRはどのようにして同じ処理時間でdoubleを取得できますか?
私はいくつかのタイミングテストを行い、このようないくつかの記事(最後のコメント)も読みました。リリースビルドでは、float値とdouble値の処理時間は同じです。
これはどのようにして可能ですか?floatがdouble値と比較して精度が低く、小さい場合、CLRはどのようにして同じ処理時間でdoubleを取得できますか?
回答:
少なくとものx86プロセッサ、上、float
及びdouble
各処理のためのFPUによって、10バイトの実数に変換されます。FPUは、FPUがサポートするさまざまな浮動小数点型に対して個別の処理ユニットを備えていません。
昔からアドバイスfloat
よりも高速でdouble
適用された100年前にほとんどのCPUはFPUを内蔵しているしませんでした(と少数の人々は別のFPUチップを持っていた)ときは、そのほとんどの浮動小数点操作がソフトウェアで行われました。これらのマシン(溶岩ピットで生成された蒸気を利用)では、s を使用した方が高速float
でした。float
sの唯一の真の利点は、占有するスペースが少ないことです(数百万の場合にのみ問題になります)。
私はCUDAを使用する小さなプロジェクトを持っていましたが、フロートも2倍よりも速いことを覚えています。かつては、ホストとデバイス間のトラフィックが低くなります(ホストはCPUであり、「通常の」RAMであり、デバイスはGPUであり、対応するRAMがあります)。ただし、データが常にデバイス上にある場合でも、速度は遅くなります。これが最近変わった、または次の世代で変わると思われることをどこかで読んだと思いますが、よくわかりません。
したがって、これらの場合、GPUは倍精度をネイティブで処理できないようであり、GLDoubleではなくGLFloatが通常使用される理由も説明します。
(私が言ったように、それは私が覚えている限りですが、CPUでfloatとdoubleを検索しているときにこれに遭遇しました。)
ただし、浮動小数点が好まれる場合もあります。たとえば、OpenGLコーディングでは、GLDoubleよりもほとんどのGPUで効率的であるため、GLFloatデータ型(通常は16ビット浮動小数点に直接マップされます)を使用するのがはるかに一般的です。
32ビットまたは64ビットシステムによって異なります。64ビットにコンパイルする場合、doubleの方が高速です。64ビット(マシンとOS)で32ビットにコンパイルすると、フロートが約30%速くなります。
public static void doubleTest(int loop)
{
Console.Write("double: ");
for (int i = 0; i < loop; i++)
{
double a = 1000, b = 45, c = 12000, d = 2, e = 7, f = 1024;
a = Math.Sin(a);
b = Math.Asin(b);
c = Math.Sqrt(c);
d = d + d - d + d;
e = e * e + e * e;
f = f / f / f / f / f;
}
}
public static void floatTest(int loop)
{
Console.Write("float: ");
for (int i = 0; i < loop; i++)
{
float a = 1000, b = 45, c = 12000, d = 2, e = 7, f = 1024;
a = (float) Math.Sin(a);
b = (float) Math.Asin(b);
c = (float) Math.Sqrt(c);
d = d + d - d + d;
e = e * e + e * e;
f = f / f / f / f / f;
}
}
static void Main(string[] args)
{
DateTime time = DateTime.Now;
doubleTest(5 * 1000000);
Console.WriteLine("milliseconds: " + (DateTime.Now - time).TotalMilliseconds);
time = DateTime.Now;
floatTest(5 * 1000000);
Console.WriteLine("milliseconds: " + (DateTime.Now - time).TotalMilliseconds);
Thread.Sleep(5000);
}
Math
doubleで動作するため、キャストは問題の一部です。しかし、あなたは私の投稿を誤って読みました。私のテストでは、パフォーマンスが向上していることがわかりました。
float
とdouble
パフォーマンスはほぼ同じであることが示されています。多くの独立したトライアルで平均すると0.3%未満の差で、各トライアルは連続的にチェーンされた変数に対して乗算、除算、および加算の演算を実行しました(コンパイラの最適化が邪魔にならないようにするため)。私はとテストの第2のセットを試してみましたMath.Sin()
とMath.Sqrt()
しても同じ結果を得ました。