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?

Foi útil?

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 floats uso. Agora, o único benefício real para floats é 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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top