Operações matemáticas simples mais rápido do que no tipo de dados float? [duplicado]
Duplicata Possível:
São duplas mais rápido do que flutua em c #?
Eu escrevi benchmark simples para verificar quanto desempenho eu posso conseguir mudardouble
tipo de dados parafloat
na minha aplicação. Aqui está o meu código:
// 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);
}
Eu obtive resultados como este (lançamento, sem depuração, CPU Intel Mobile Core Duo T2500 2.0GHz 2MB):
Preparing data 5275,6862ms
Multiplying floats: 442,7865ms
Multiplying doubles: 169,4028ms
Dividing floats: 550,7052ms
Dividing doubles: 164,1607ms
Fiquei surpreso, que as operações emdouble
são quase 3 vezes mais rápidos que as operações emfloat
. Eu procurei por "double float" aqui, e achei isso:
Está usando o dobro mais rápido que o float?
A melhor resposta está focada na arquitetura da CPU, mas não posso concordar com isso.
Eu suspeito que algo mais está causando baixo desempenho em carros alegóricos, porque minha CPU com Intel SSE deve ser capaz de multiplicar ou dividir 4 flutuadores de uma só vez (instruções de ponto flutuante compactadas) ou 2 duplas de uma só vez. Então, os carros alegóricos devem ser mais rápidos.
Talvez o compilador (ou clr em .net) esteja otimizando o uso da memória de alguma forma?
Existe alguma maneira de otimizá-lo e tornar o float mais rápido?
Por favor não relate duplicado, eu vi outras perguntas e elas não me satisfazem.
Meus resultados depois de mudar o método para gerar floats agora parecem bem (sugerido por Servy):
Preparing data 1367,0678ms
Multiplying floats: 109,8742ms
Multiplying doubles: 149,9555ms
Dividing floats: 167,0079ms
Dividing doubles: 168,6821ms