A>Функции разные для разных аргументов. Для коротких (32-битных) float и для длинных (64-битных) double. A>Так вот... для 32-битных float функции реализованы на многочленах, использующих float (и это нормально).
A>А для 64-битных double... на целых числах!!!
A>Соответсвенно скорость падает в СТО раз.
Разбираюсь тут с библиотекой glibc. Вот этой: https://www.gnu.org/software/libc/download.html
Работа связана с тем, что нужно водрузить эту библиотеку на отечественный процессор.
Обнаружилась странная вещь.
В библиотеке есть математические функции — синусы и логарифмы и прочее.
Для i386 и тому подобного эти функции реализованы на ассемблере (что нормально).
Для других архитектур есть некая замена, написанная на С.
Функции разные для разных аргументов. Для коротких (32-битных) float и для длинных (64-битных) double.
Так вот... для 32-битных float функции реализованы на многочленах, использующих float (и это нормально).
Исходники лежат здесь: (корень)/sysdeps/ieee754/flt-32
А для 64-битных double... на целых числах!!!
Исходники лежат здесь: (корень)/sysdeps/ieee754/dbl-64
Соответсвенно скорость падает в СТО раз.
Здравствуйте, alpha21264, Вы писали:
A>А для 64-битных double... на целых числах!!! A>Исходники лежат здесь: (корень)/sysdeps/ieee754/dbl-64 A>Соответсвенно скорость падает в СТО раз.
1. Стоит почитать коммит логи. Возможно там есть объяснение.
Например не исключено что в другом варианте будет теряться точность.
Вообще вычисления математических функций с высокой точностью очень сложная задача с кучей не очевидных моментов.
A>Разбираюсь тут с библиотекой glibc. Вот этой: A>https://www.gnu.org/software/libc/download.html A>Работа связана с тем, что нужно водрузить эту библиотеку на отечественный процессор. A>Обнаружилась странная вещь. A>В библиотеке есть математические функции — синусы и логарифмы и прочее. A>Для i386 и тому подобного эти функции реализованы на ассемблере (что нормально). A>Для других архитектур есть некая замена, написанная на С. A>Функции разные для разных аргументов. Для коротких (32-битных) float и для длинных (64-битных) double. A>Так вот... для 32-битных float функции реализованы на многочленах, использующих float (и это нормально). A>Исходники лежат здесь: (корень)/sysdeps/ieee754/flt-32 A>А для 64-битных double... на целых числах!!! A>Исходники лежат здесь: (корень)/sysdeps/ieee754/dbl-64 A>Соответсвенно скорость падает в СТО раз.
A>Это вообще нормально, или я что-то пропустил?
А gcc в оптимизированном режиме случайно не заменяет эти функции своими вызовами?
Здравствуйте, vsb, Вы писали:
vsb>Здравствуйте, alpha21264, Вы писали:
A>>Разбираюсь тут с библиотекой glibc. Вот этой: A>>А для 64-битных double... на целых числах!!! A>>Исходники лежат здесь: (корень)/sysdeps/ieee754/dbl-64 A>>Соответсвенно скорость падает в СТО раз.
A>>Это вообще нормально, или я что-то пропустил?
vsb>А gcc в оптимизированном режиме случайно не заменяет эти функции своими вызовами?
Нуу... понимаешь... gcc-то для этого процессора тоже мы пишем.
Нет, не подменяет. Да и не должен. Это же функции.
Как компилятору знать, что делают эти функции и на что их менять?
Здравствуйте, alpha21264, Вы писали:
vsb>>А gcc в оптимизированном режиме случайно не заменяет эти функции своими вызовами?
A>Нуу... понимаешь... gcc-то для этого процессора тоже мы пишем. A>Нет, не подменяет. Да и не должен. Это же функции. A>Как компилятору знать, что делают эти функции и на что их менять?
Есть стандартные функции и при их использовании компилятор часто вставляет не вызов функции, а какой-то другой код или вызов другой функции. Например puts вместро printf("bla\n") или свою реализацию вместо вызова memcpy.
Впрочем синус он вроде не заменяет, так что в данном случае это не то.
Здравствуйте, smeeld, Вы писали:
S>Здравствуйте, alpha21264, Вы писали:
A>>Функции разные для разных аргументов. Для коротких (32-битных) float и для длинных (64-битных) double. A>>Так вот... для 32-битных float функции реализованы на многочленах, использующих float (и это нормально).
A>>А для 64-битных double... на целых числах!!!
A>>Соответсвенно скорость падает в СТО раз.
S>С чего это падает?
Ну посмотри файл
/sysdeps/ieee754/dbl-64/e_atan2.c
Это может быстро работать?
A>Разбираюсь тут с библиотекой glibc. Вот этой: A>Так вот... для 32-битных float функции реализованы на многочленах, использующих float (и это нормально). A>Исходники лежат здесь: (корень)/sysdeps/ieee754/flt-32 A>А для 64-битных double... на целых числах!!! A>Исходники лежат здесь: (корень)/sysdeps/ieee754/dbl-64 A>Соответсвенно скорость падает в СТО раз. A>Это вообще нормально, или я что-то пропустил?
А можно конкретный пример что именно реализовано на "целых" числах?
Например sysdeps/ieee754/dbl-64/e_atan2.c:
double
SECTION
__ieee754_atan2 (double y, double x)
{
int i, de, ux, dx, uy, dy;
static const int pr[MM] = { 6, 8, 10, 20, 32 };
double ax, ay, u, du, u9, ua, v, vv, dv, t1, t2, t3, t7, t8,
z, zz, cor, s1, ss1, s2, ss2;
Здравствуйте, smeeld, Вы писали:
S>Здравствуйте, alpha21264, Вы писали:
A>>Это может быстро работать?
S>В упор не вижу проблемы, все вычисления тут
Ну, вероятно у тебя что-то со зрением.
Это что-то выражается в том, что ты глядя на код не можешь прикинуть, какая производительность получится.
Получается в сто раз меньше, чем у flt-32. Ну это просто результат эксперимента такой.
Здравствуйте, vsb, Вы писали:
vsb>А gcc в оптимизированном режиме случайно не заменяет эти функции своими вызовами?
Как минимум на x86-64 (aka amd64) в SSE* команд нет, используются эти функции.
Для x86-32 aka i386 дёргается FPU, если точности хватает, иначе краевые случаи отрабатываются своими средствами. На fast-math режиме могут многое сократить, например, делать pow() через FPU.
Здравствуйте, alpha21264, Вы писали:
A>Нуу... понимаешь... gcc-то для этого процессора тоже мы пишем. A>Нет, не подменяет. Да и не должен. Это же функции. A>Как компилятору знать, что делают эти функции и на что их менять?
Про некоторые функции он таки много чего знает. Например, он умеет заменять printf() на puts() там, где уместно.