Flutuar vs Duplo Desempenho
-
03-07-2019 - |
Pergunta
Eu fiz alguns testes de tempo e também ler alguns artigos como esta (último comentário), e parece que na versão de construção, bóia e valores double tomar a mesma quantidade de tempo de processamento.
Como isso é possível? Quando float é menos preciso e menor em comparação com valores double, como pode o CLR obter duplos para o mesmo tempo de processamento?
Solução
x86 processadores, pelo menos, float
e double
cada um deles será convertido para um verdadeiro 10 bytes pela FPU para processamento. Será que o FPU não tem unidades de processamento separadas para os diferentes tipos de ponto flutuante que suporta.
O antigo conselho que float
é mais rápido que double
aplicado 100 anos atrás, quando a maioria das CPUs não têm built-in FPUs (e poucas pessoas tinham fichas FPU separados), de modo a manipulação mais de ponto flutuante foi feito em software. Nestas máquinas (que foram alimentados por vapor gerado pelos poços de lava), ele foi mais rápido para float
s uso. Agora, o único benefício real para float
s é que eles ocupam menos espaço (que só importa se você tem milhões deles).
Outras dicas
Eu tive um pequeno projeto onde eu costumava CUDA e me lembro que flutuam foi mais rápido do que o dobro lá, também. Para uma vez que o tráfego entre o Host e do dispositivo é menor (Host é a CPU ea RAM "normal" e do dispositivo é o GPU e da RAM não correspondente). Mas mesmo que reside a dados no dispositivo o tempo todo é mais lento. Acho que eu li em algum lugar que isso mudou recentemente ou é suposto a mudar com a próxima geração, mas eu não tenho certeza.
Assim, parece que a GPU simplesmente não pode lidar com precisão dupla nativamente nesses casos, o que também explicaria por que GLfloat geralmente é usado em vez de GLDouble.
(Como eu disse, é apenas na medida em que me lembro, só tropeçou em este enquanto procura flutuador vs. dupla em uma CPU.)
Depende 32-bit ou 64-bit sistema. Se você compilar a 64-bit, dupla será mais rápido. Compilado para 32 bits em 64 bits (máquina e OS) fez flutuar em torno de 30% mais rápido:
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);
}
Existem ainda alguns casos em que os flutuadores são preferidos no entanto - com OpenGL de codificação, por exemplo, é muito mais comum de utilizar o tipo de dados GLfloat (geralmente mapeadas directamente para 16 bits flutuador), uma vez que é mais eficiente na maioria das GPUs que GLDouble