我有以下功能:
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 次多项式插值非常愚蠢)。
但是,我对这种方法很不满意:
- 我错过了一些明显的危险
alloca
吗? - 有没有更好的方法来避免这里的堆分配?