Вопрос

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

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

Это было полезно?

Решение

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

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

Другие советы

У меня был небольшой проект, в котором я использовал CUDA, и я помню, что float там тоже был быстрее, чем double. Как только трафик между Хостом и Устройством становится меньше (Хост - это ЦП, а «нормальная» ОЗУ и Устройство - это ГП и соответствующая ОЗУ). Но даже если данные постоянно находятся на устройстве, это медленнее. Мне кажется, я где-то читал, что это недавно изменилось или должно измениться со следующим поколением, но я не уверен.

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

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

Это зависит от 32-битной или 64-битной системы. Если вы компилируете в 64-битную версию, double будет быстрее. Скомпилированный в 32-битный режим на 64-битном (машина и ОС) ускорился на 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);
    }

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top