У меня есть следующие функции:Является ли это хорошей причиной для использования alloca?
double
neville (double xx, size_t n, const double *x, const double *y, double *work);
, который выполняет интерполяцию Лагранжа в xx
с использованием n
точек, хранящихся в x
и y
. Массив work
имеет размер 2 * n
. Так как это полиномиальная интерполяция, n
находится в приблизительном размере ~ 5, очень редко больше 10.
Эта функция агрессивно оптимизирована и должна быть вызвана в плотных петлях. Профилирование предполагает, что куча, распределяющая рабочий массив в цикле, плоха. К сожалению, я должен упаковать это в класс функций, и клиенты должны не знать о рабочем массиве.
На данный момент, я использую шаблон целочисленный аргумент для степени и std::array
, чтобы избежать динамического распределения work
массива:
template <size_t n>
struct interpolator
{
double operator() (double xx) const
{
std::array<double, 2 * n> work;
size_t i = locate (xx); // not shown here, no performance impact
// due to clever tricks + nice calling patterns
return neville (xx, n, x + i, y + i, work.data());
}
const double *x, *y;
};
Это было бы невозможно хранить массив работы в качестве изменяемого элемента из класс, но operator()
предполагается использовать одновременно несколькими потоками. Эта версия в порядке, если вы знаете n
во время компиляции.
Теперь мне нужно указать параметр n
во время выполнения. Мне интересно, о чем-то вроде этого:
double operator() (double xx) const
{
auto work = static_cast<double*> (alloca (n * sizeof (double)));
...
Некоторые колокола кольца при использовании alloca
: Я, конечно, будет иметь шапку на n
, чтобы избежать alloca
вызова переполнения (во всяком случае, это довольно глупо использовать степень 100 полиномиальная интерполяция).
Я совершенно unconfortable с подходом, однако:
- Я пропускаю некоторые очевидные опасности
alloca
? - Есть ли лучший способ избежать выделения кучи здесь?
Не можете ли вы просто написать эту функцию в C и использовать C99 VLAs? – 2013-04-30 18:45:26
@KonradRudolph 'double neville (double xx, size_t n, const double * x, const double * y, double * work);' - вам нужна перегрузка оператора для записи этой функции? Ничего себе, я никогда не знал! – 2013-04-30 18:59:23
@ H2CO3 Хе-хе, поймал меня. Что ж, мой последний аргумент в том, что я сильно не люблю связывать код C и C++. Конечно, нет реальной проблемы (если все сделано правильно! И я столкнулся с множеством библиотек C, которые сделали это неправильно и вызвали у меня большую боль). Но тогда я вижу нулевую выгоду от использования VLA через 'alloca', но, может быть, я чего-то не хватает ...? –