Proste operacje matematyczne szybciej na podwójnym niż na zmiennym typie danych? [duplikować]
Możliwy duplikat:
Czy podwaja się szybciej niż pływa w c #?
Napisałem prosty test porównawczy, aby sprawdzić, ile wydajności mogę zmienićdouble
typ danych dofloat
w mojej aplikacji. Oto mój kod:
// my form:
// one textbox: textbox1 (MultiLine property set to true)
// one button: button1 with event button1_Click
private void button1_Click(object sender, EventArgs e)
{
int num = 10000000;
float[] floats1 = new float[num];
float[] floats2 = new float[num];
float[] floatsr = new float[num]; // array for results
double[] doubles1 = new double[num];
double[] doubles2 = new double[num];
double[] doublesr = new double[num]; // array for results
Stopwatch stw = new Stopwatch();
log("Preparing data");
Random rnd = new Random();
stw.Start();
for (int i = 0; i < num; i++)
{
floats1[i] = NextFloat(rnd);
floats2[i] = NextFloat(rnd);
doubles1[i] = rnd.NextDouble();
doubles2[i] = rnd.NextDouble();
}
stw.Stop();
log(stw.Elapsed.TotalMilliseconds.ToString()+"ms");
stw.Reset();
log("");
stw.Start();
for (int i = 0; i <# i++)
{
floatsr[i] = floats1[i] * floats2[i];
}
stw.Stop();
log("Multiplying floats: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
stw.Reset();
stw.Start();
for (int i = 0; i < num; i++)
{
doublesr[i] = doubles1[i] * doubles2[i];
}
stw.Stop();
log("Multiplying doubles: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
stw.Reset();
stw.Start();
for (int i = 0; i < num; i++)
{
floatsr[i] = floats1[i] / floats2[i];
}
stw.Stop();
log("Dividing floats: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
stw.Reset();
stw.Start();
for (int i = 0; i < num; i++)
{
doublesr[i] = doubles1[i] / doubles2[i];
}
stw.Stop();
log("Dividing doubles: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
stw.Reset();
}
private void log(string text)
{
textBox1.Text = textBox1.Text + text + Environment.NewLine;
}
// I found that function somewhere on stackoverflow
static float NextFloat(Random random)
{
double mantissa = (random.NextDouble() * 2.0) - 1.0;
double exponent = Math.Pow(2.0, random.Next(-126, 128));
return (float)(mantissa * exponent);
}
Mam takie wyniki (wydanie, brak debugowania, Intel Mobile Core Duo T2500 2.0GHz 2MB CPU):
Preparing data 5275,6862ms
Multiplying floats: 442,7865ms
Multiplying doubles: 169,4028ms
Dividing floats: 550,7052ms
Dividing doubles: 164,1607ms
Byłem zaskoczony tymi operacjamidouble
są prawie 3 razy szybsze niż operacjefloat
. Szukałem tutaj „double float” i znalazłem to:
Czy używanie podwójnego szybciej niż float?
Najlepsza odpowiedź koncentruje się na architekturze procesora, ale nie mogę się z tym zgodzić.
Podejrzewam, że coś innego powoduje niską wydajność na pływakach, ponieważ mój procesor z Intel SSE powinien być w stanie pomnożyć lub podzielić 4 pływaki na raz (instrukcje zmiennoprzecinkowe) lub 2 podwójne na raz. Więc pływaki powinny być szybsze.
Może kompilator (lub clr w .net) jakoś optymalizuje wykorzystanie pamięci?
Czy jest jakiś sposób na zoptymalizowanie go i szybsze tempo?
Nie zgłaszaj duplikatów, widziałem inne pytania i mnie nie satysfakcjonują.
Moje wyniki po zmianie metody generowania pływaków teraz wyglądają dobrze (sugerowane przez Servy):
Preparing data 1367,0678ms
Multiplying floats: 109,8742ms
Multiplying doubles: 149,9555ms
Dividing floats: 167,0079ms
Dividing doubles: 168,6821ms