Float vs Double Performance

Я провел несколько тестов времени, а также прочитал некоторые статьи, такие как этот (последний комментарий), и он выглядит как в Release build, float и двойные значения занимают одинаковое количество времени обработки.

Как это возможно? Когда float менее точен и меньше по сравнению с двойными значениями, как CLR может удваиваться в одно время обработки?

Ответ 1

На процессорах x86, по крайней мере, float и double будут преобразованы в 10-байтовое реальное FPU для обработки. FPU не имеет отдельных блоков обработки для различных поддерживаемых типов с плавающей запятой.

Старый совет, который float работает быстрее, чем double, примененный 100 лет назад, когда большинство процессоров не имели встроенных FPU (и у немногих людей были отдельные чипы FPU), поэтому большинство операций с плавающей запятой было сделано в программном обеспечении. На этих машинах (которые питались от пара, создаваемого ямами лавы), было быстрее использовать float s. Теперь единственным реальным преимуществом float является то, что они занимают меньше места (что имеет значение только в том случае, если у вас есть миллионы).

Ответ 2

У меня был небольшой проект, в котором я использовал CUDA, и я помню, что плавать было быстрее, чем вдвое. На этот раз трафик между хостом и устройством ниже (хост - это центральный процессор, а "нормальная" ОЗУ и устройство - это графический процессор и соответствующая оперативная память). Но даже если данные постоянно находятся на устройстве, это замедляется. Я думаю, что я где-то читал, что это изменилось недавно или должно измениться со следующим поколением, но я не уверен.

Итак, кажется, что GPU просто не может обрабатывать двойную точность изначально в этих случаях, что также объясняет, почему GLFloat обычно используется, а не GLDouble.

(Как я уже сказал, только насколько я помню, просто наткнулся на это при поиске float против double на CPU.)

Ответ 3

Это зависит от 32-разрядной или 64-разрядной системы. Если вы скомпилируете до 64 бит, двойной будет быстрее. Скомпилированный в 32-разрядный 64-разрядный (машина и ОС) сделал float примерно на 30% быстрее:

    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);
    }

Ответ 4

Есть еще некоторые случаи, когда предпочтительны поплавки - например, с использованием кодирования OpenGL, гораздо более распространенным для использования типа данных GLFloat (обычно сопоставленного непосредственно с 16-битным поплавком), поскольку он более эффективен для большинства графических процессоров, чем GLDouble.