как double считать со скоростью float
От: ZegSoft Россия  
Дата: 08.07.11 10:36
Оценка:
Собственно вопрос в следующем. Есть массив объектов, членами которого являются переменные типа double.
Есть алгоритмы, производящие сложные матемитические расчеты над этим объектами. Выичсления довольно ресурсоемкие, поэтому время расчета доходит до нескольких минут.
Эксперименты показали, что если в некоторых иp эти[ алгоритмов заменить double на float, то точность расчета остается на приемлемом уровне, а вот скорость расчета увеличивается примерно на 30%, что в абсолютном измерении составляет от одной до двух минут. То есть разница весьма существенная.
Проблема в том, что такой подход возможен только для части алгоритмов. Для других же алгоритмов менять double на float нельзя, так как точности float не хватает для успешного завершения расчетов (методы расчета не сходятся).
Есть ли какой-то способ или программные конструкции, позволяюшие производить вычисления над double как над float?.
Пока проблему решил через шаблоны. То есть создаются две копии объектов: float-версия и double-версия. float-версия передается в алгоритмы, которые допускают расчеты с точностью float, а double версия в остальные алгоритмы. Но при таком подходе возникает проблема синхронизации версий. В принципе, алгоритмы взаимонезависимы. Но заранее предугадать, какой алгоритм вызовет пользователь невозможно. Поэтому приходится поддерживать сразу 2 версии объектов, что очень неудобно.
Что можете посоветовать? Может быть в boost есть что-нить полезное?
Re: как double считать со скоростью float
От: ZegSoft Россия  
Дата: 08.07.11 10:38
Оценка:
Сразу извиняюсь за опечатки((( Никак к новой клаве не привыкну. Когда уже на форуме появится возможность редактирования сообщений???????????
Re: как double считать со скоростью float
От: watch-maker  
Дата: 08.07.11 12:40
Оценка: 1 (1)
Здравствуйте, ZegSoft, Вы писали:

ZS>Пока проблему решил через шаблоны. То есть создаются две копии объектов: float-версия и double-версия. float-версия передается в алгоритмы, которые допускают расчеты с точностью float, а double версия в остальные алгоритмы. Но при таком подходе возникает проблема синхронизации версий. В принципе, алгоритмы взаимонезависимы. Но заранее предугадать, какой алгоритм вызовет пользователь невозможно. Поэтому приходится поддерживать сразу 2 версии объектов, что очень неудобно.

По моему, вполне хорошее решение с шаблонами. Непонятно в чём же именно заключается это «очень неудобно».

ZS>Есть ли какой-то способ или программные конструкции, позволяюшие производить вычисления над double как над float?.

Вообще, как всегда есть частные решения. Например, в x87-fpu есть пара команд fldcw и fstcw, которые позволяют менять точность вычислений прямо во время работы программы. То есть можно просто в нужный момент сказать процессору, чтобы он считал все double с точностью float. Разумеется, это поможет только если тормозят такие инструкции как, например, деление чисел (их время работы сильно зависит от точности), а если тормоза вызваны, скажем, пропускной способностью памяти, то ничего не изменится, ибо fstcw не сделает из восьми байт четыре.
Но такой путь мне кажется всё-таки не очень красивым. Ведь даже на x86 архитектуре всё больше вычислений с плавающей точкой проводится не на x87, а на sse. А с последним такой трюк не работает, так как double и float числа обрабатываются разными семействами инструкций, то есть нужно опять же поддерживать два варианта функций.
Re[2]: как double считать со скоростью float
От: ZegSoft Россия  
Дата: 08.07.11 13:08
Оценка:
Здравствуйте, watch-maker, Вы писали:

WM>Здравствуйте, ZegSoft, Вы писали:


ZS>>Пока проблему решил через шаблоны. То есть создаются две копии объектов: float-версия и double-версия. float-версия передается в алгоритмы, которые допускают расчеты с точностью float, а double версия в остальные алгоритмы. Но при таком подходе возникает проблема синхронизации версий. В принципе, алгоритмы взаимонезависимы. Но заранее предугадать, какой алгоритм вызовет пользователь невозможно. Поэтому приходится поддерживать сразу 2 версии объектов, что очень неудобно.

WM>По моему, вполне хорошее решение с шаблонами. Непонятно в чём же именно заключается это «очень неудобно».

Неудобство в увеличении времени создания массивов таких объектов в два раза. И второе неудобство — это проблема синхронизации данных, хранящихся в каждой версии. Допустим алгоритм работает с float-версией. После завершения работы алгоритма нужно обновить поля double-версии, чтобы была возможность применить алгоритмы, поддерживающие только double версию. Каким образом это реализовывать? Перспектива прописывания ручками присваение полей от двух версий как-то не привлекает.
Re[3]: как double считать со скоростью float
От: minorlogic Украина  
Дата: 08.07.11 16:09
Оценка:
Здравствуйте, ZegSoft, Вы писали:

ZS>Неудобство в увеличении времени создания массивов таких объектов в два раза. И второе неудобство — это проблема синхронизации данных, хранящихся в каждой версии. Допустим алгоритм работает с float-версией. После завершения работы алгоритма нужно обновить поля double-версии, чтобы была возможность применить алгоритмы, поддерживающие только double версию. Каким образом это реализовывать? Перспектива прописывания ручками присваение полей от двух версий как-то не привлекает.


Например boost::ublas делает такое конвертирование автоматом. И кстати умеет биндится на разные числодробильные библиотеки.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[2]: как double считать со скоростью float
От: _niko_ Россия  
Дата: 08.07.11 16:12
Оценка: :)
Здравствуйте, ZegSoft, Вы писали:

ZS>Когда уже на форуме появится возможность редактирования сообщений???????????


Никогда, в этом вся соль! Ибо за свои слова надо отвечать
Re: как double считать со скоростью float
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 09.07.11 17:12
Оценка:
Здравствуйте, ZegSoft, Вы писали:

ZS>Что можете посоветовать? Может быть в boost есть что-нить полезное?


У меня была подобная проблема. Решилась изменением опций компилятора: использовать SSE2.
Re[2]: как double считать со скоростью float
От: ZegSoft Россия  
Дата: 09.07.11 17:35
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Здравствуйте, ZegSoft, Вы писали:


ZS>>Что можете посоветовать? Может быть в boost есть что-нить полезное?


N>У меня была подобная проблема. Решилась изменением опций компилятора: использовать SSE2.


А чуть подробнее можно?
Re[3]: как double считать со скоростью float
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 09.07.11 17:55
Оценка:
Здравствуйте, ZegSoft, Вы писали:

N>>У меня была подобная проблема. Решилась изменением опций компилятора: использовать SSE2.


ZS>А чуть подробнее можно?


MSVC: C++ -> Code generation -> Enable enhanced instruction set -> SSE2
Ну и можно: C++ -> Code generation -> Floating point model -> Fast
Re[4]: как double считать со скоростью float
От: ZegSoft Россия  
Дата: 09.07.11 17:59
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Здравствуйте, ZegSoft, Вы писали:


N>>>У меня была подобная проблема. Решилась изменением опций компилятора: использовать SSE2.


ZS>>А чуть подробнее можно?


N>MSVC: C++ -> Code generation -> Enable enhanced instruction set -> SSE2

N>Ну и можно: C++ -> Code generation -> Floating point model -> Fast

И на сколько это подняло производительность?? Как я понимаю, в 6-й студии такого нет?(
Re[2]: как double считать со скоростью float
От: jakor  
Дата: 09.07.11 17:59
Оценка:
WM>Но такой путь мне кажется всё-таки не очень красивым. Ведь даже на x86 архитектуре всё больше вычислений с плавающей точкой проводится не на x87, а на sse. А с последним такой трюк не работает, так как double и float числа обрабатываются разными семействами инструкций, то есть нужно опять же поддерживать два варианта функций.
на ССЕ можно ускорить просто в говно.
если двойная точность нужна — то одни и те же инструкции и дабл и флоат могут посчитать. В принципе и ключик в МСВЦ это поможет сделать, а лучше всего ручками прописать.
Re[3]: как double считать со скоростью float
От: ZegSoft Россия  
Дата: 09.07.11 18:03
Оценка:
Здравствуйте, jakor, Вы писали:


WM>>Но такой путь мне кажется всё-таки не очень красивым. Ведь даже на x86 архитектуре всё больше вычислений с плавающей точкой проводится не на x87, а на sse. А с последним такой трюк не работает, так как double и float числа обрабатываются разными семействами инструкций, то есть нужно опять же поддерживать два варианта функций.

J>на ССЕ можно ускорить просто в говно.
J>если двойная точность нужна — то одни и те же инструкции и дабл и флоат могут посчитать. В принципе и ключик в МСВЦ это поможет сделать, а лучше всего ручками прописать.

А 6-я студия такое наверное не поддерживает???(
Re[3]: как double считать со скоростью float
От: ZegSoft Россия  
Дата: 09.07.11 18:30
Оценка:
Здравствуйте, jakor, Вы писали:


WM>>Но такой путь мне кажется всё-таки не очень красивым. Ведь даже на x86 архитектуре всё больше вычислений с плавающей точкой проводится не на x87, а на sse. А с последним такой трюк не работает, так как double и float числа обрабатываются разными семействами инструкций, то есть нужно опять же поддерживать два варианта функций.

J>на ССЕ можно ускорить просто в говно.
J>если двойная точность нужна — то одни и те же инструкции и дабл и флоат могут посчитать. В принципе и ключик в МСВЦ это поможет сделать, а лучше всего ручками прописать.

Попробовал скомпилить с этими ключами — никакого ускорения нет.
Насколько я понимаю, вся проблема в том, что алгоритм делает не тупое "перемалывание массивов данных", а элементы массивов взаимосвязаны. Результаты расчета в элементе j зависят от результатов расчета элемента i. Насколько я понял, SSE — это что-то наподобии конвейеров? В такой постановке они не могут дать эффекта.
Re[3]: как double считать со скоростью float
От: ArtDenis Россия  
Дата: 09.07.11 18:41
Оценка:
Здравствуйте, jakor, Вы писали:

J>если двойная точность нужна — то одни и те же инструкции и дабл и флоат могут посчитать. В принципе и ключик в МСВЦ это поможет сделать, а лучше всего ручками прописать.


Компилятор С++ от MS практически не поддерживает автоматическую векторизацию для SSE. Ощутимого ускорения от включения этого ключа не будет. Надо всё писать ручками.
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[4]: как double считать со скоростью float
От: ZegSoft Россия  
Дата: 09.07.11 18:44
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>Здравствуйте, jakor, Вы писали:


J>>если двойная точность нужна — то одни и те же инструкции и дабл и флоат могут посчитать. В принципе и ключик в МСВЦ это поможет сделать, а лучше всего ручками прописать.


AD>Компилятор С++ от MS практически не поддерживает автоматическую векторизацию для SSE. Ощутимого ускорения от включения этого ключа не будет. Надо всё писать ручками.


Насколько сложные будут модификации кода?? в чем их суть? где об этом можно почитать?
Re[4]: как double считать со скоростью float
От: ArtDenis Россия  
Дата: 09.07.11 18:44
Оценка:
Здравствуйте, ZegSoft, Вы писали:

ZS>...SSE — это что-то наподобии конвейеров?


Одна из возможностей SSE — это параллельное выполнение нескольких однотипных операций с числами на одном ядре процессора.
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[5]: как double считать со скоростью float
От: ZegSoft Россия  
Дата: 09.07.11 18:50
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>Здравствуйте, ZegSoft, Вы писали:


ZS>>...SSE — это что-то наподобии конвейеров?


AD>Одна из возможностей SSE — это параллельное выполнение нескольких однотипных операций с числами на одном ядре процессора.


Ну то есть это конвейеры получается?? Изменениея практически такие же, как и при подготовке для CUDA?? Проблема в том, что распараллелить алгоритм проблематично. Элементы массива связаны друг с другом. Результаты вычисления полей одного элемента, зависят от полей другого элемента.
Re[5]: как double считать со скоростью float
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 09.07.11 19:18
Оценка:
Здравствуйте, ZegSoft, Вы писали:

ZS>И на сколько это подняло производительность?? Как я понимаю, в 6-й студии такого нет?(


Да, в 6-й нет. Подняло чуть ли не в двое.
Re: как double считать со скоростью float
От: LaptevVV Россия  
Дата: 09.07.11 19:29
Оценка:
Здравствуйте, ZegSoft, Вы писали:

ZS>Что можете посоветовать? Может быть в boost есть что-нить полезное?

Использовать SSE.
Но вообще вопрос интересный. Дело видимо, в загрузке-сохранении регистров, так как сами вычисления производятся для обоих типов на 80-битных регистрах.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[6]: как double считать со скоростью float
От: ArtDenis Россия  
Дата: 10.07.11 03:09
Оценка:
Здравствуйте, ZegSoft, Вы писали:

ZS>Ну то есть это конвейеры получается??

Ну смотря что назвать конвейером. По мне так — нет. Конвейер в CPU работает неявно. А для SSE нужно явно указывать операции действий с векторами чисел.

ZS>Изменениея практически такие же, как и при подготовке для CUDA??

Я не разу не использовал CUDA, но думаю что да, типа того

ZS>Проблема в том, что распараллелить алгоритм проблематично. Элементы массива связаны друг с другом. Результаты вычисления полей одного элемента, зависят от полей другого элемента.

Ну значит такой вариант ускорения не пойдёт.
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.