Flutuação vs Desempenho Duplo

Eu fiz alguns testes de tempo e também li alguns artigos como este (último comentário), e parece que na versão Build, float e double valores tomam a mesma quantidade de tempo de processamento.

Como isso é possível? Quando float é menos preciso e menor comparado a valores duplos, como o CLR pode dobrar no mesmo tempo de processamento?

Em processadores x86, pelo menos, float e double serão convertidos para um real de 10 bytes pelo FPU para processamento. O FPU não possui unidades de processamento separadas para os diferentes tipos de ponto flutuante que ele suporta.

O velho conselho que é float é mais rápido do que o double aplicado 100 anos atrás, quando a maioria das CPUs não tinha FPUs embutidos (e poucas pessoas tinham chips FPU separados), então a maioria das manipulações em ponto flutuante era feita em software. Nessas máquinas (que eram movidas pelo vapor gerado pelos poços de lava), era mais rápido usar float . Agora, o único benefício real de float é que eles ocupam menos espaço (o que só importa se você tiver milhões deles).

Eu tive um pequeno projeto onde usei CUDA e lembro que o float era mais rápido do que o dobro também. Por uma vez o tráfego entre Host e Device é menor (Host é a CPU e a RAM “normal” e Device é a GPU e a RAM correspondente lá). Mas, mesmo que os dados residam no dispositivo, todo o tempo é mais lento. Acho que li em algum lugar que isso mudou recentemente ou que deveria mudar com a próxima geração, mas não tenho certeza.

Assim, parece que a GPU simplesmente não consegue lidar com precisão dupla nativamente nesses casos, o que também explica por que o GLFloat é normalmente usado em vez de GLDouble.

(Como eu disse, é só até onde eu consigo me lembrar, apenas tropeçar nisso enquanto procurava float vs. double em uma CPU.)

Depende do sistema de 32 ou 64 bits . Se você compilar para 64 bits, o dobro será mais rápido. Compilado em 32 bits em 64 bits (máquina e sistema operacional) tornou o float 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); } 

Ainda existem alguns casos em que os floats são preferidos – com a codificação OpenGL, por exemplo, é muito mais comum usar o tipo de dados GLFloat (geralmente mapeado diretamente para 16 bit float), pois é mais eficiente na maioria das GPUs do que GLDouble.