Существует ряд Политики которые могут быть использованы для торговли точность для производительности:
- Внутреннее продвижение: по умолчанию функции с
float
аргументы оцениваются по ДП
точность внутри для обеспечения полной точности в результате. Точно так же ДП
прецизионные функции оцениваются по long ДП
точность внутри по умолчанию. Изменение этих по умолчанию может иметь значительное преимущество в скорости за счет точности, обратите внимание также, что оценка с использованием float
внутри может привести к количественной нестабильности для некоторых из более сложных алгоритмов, мы предлагаем вам использовать эту опцию с осторожностью.
- Точность цели: только потому, что вы выбираете для оценки на
ДП
точность не означает, что вы обязательно хотите нацелить полную 16-значную точность, если вы хотите изменить по умолчанию (полная точность машины) на все, что «достаточно» для вашего конкретного случая использования.
Например, предположим, что вы хотите оценить ДП
прецизионные функции на ДП
точность внутри, вы можете изменить глобальный дефолт, пройдя -DBOOST_MATH_PROMOTE_DOUBLE_POLICY=false
на командной строке, или в точке вызова через что-то подобное:
double val = boost::math::erf(my_argument, boost::math::policies::make_policy(boost::math::policies::promote_double<false>()));
Однако более простым вариантом может быть:
#include <boost/math/special_functions.hpp>
namespace math{
namespace precise{
typedef boost::math::policies::policy<> accurate_policy;
BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(accurate_policy)
}
namespace fast{
using namespace boost::math::polcies;
typedef policy<promote_double<false> > fast_policy;
BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(fast_policy)
}
}
А теперь можно позвонить:
math::accurate::tgamma(x);
Для "аккуратной" версии tgamma, и:
math::fast::tgamma(x);
Для более быстрой версии.
Если бы мы хотели изменить целевую точность (до 9 десятичных мест), а также используемый тип оценки, мы могли бы сделать:
namespace math{
namespace fast{
using namespace boost::math::polcies;
typedef policy<promote_double<false>, digits10<9> > fast_policy;
BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(fast_policy)
}
}
Можно сделать то же самое с классами распределения:
#include <boost/math/distributions.hpp>
namespace math{ namespace fast{
using namespace boost::math::polcies;
typedef policy<promote_float<false> > fast_float_policy;
BOOST_MATH_DECLARE_DISTRIBUTIONS(float, fast_float_policy)
}}
float p_val = cdf(math::fast::normal(1.0f, 3.0f), 0.25f);
Вот как эти варианты меняют относительную производительность дистрибутивов на Linux:
[table_Distribution_performance_comparison_for_ Different_performance_options_with_GNU_C_version_5_1_0_on_linux]