私は、次の機能を有する:これはallocaを使う良い理由ですか?
double
neville (double xx, size_t n, const double *x, const double *y, double *work);
x
とy
に格納されているn
点を用いてxx
でラグランジュ補間を行います。 work
アレイのサイズは2 * n
です。これは多項式補間であるため、n
は〜5の球場にあり、非常にまれに10を超えることはほとんどありません。
この関数は積極的に最適化されており、きついループで呼び出されるはずです。プロファイリングでは、ループ内のワーク配列を割り当てるヒープが悪いことが示唆されています。残念ながら、私はこれを関数に似たクラスにパッケージ化し、クライアントはワーク配列を認識しなくてはなりません。の可変メンバーとして作業配列を格納することも可能だったでしょう
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;
};
:
は今のところ、私はwork
配列の動的割り当てを避けるために、学位やstd::array
のテンプレート整数の引数を使用しますしかし、operator()
は、複数のスレッドによって同時に使用されることになっています。このバージョンはコンパイル時にn
を知っていればOKです。
実行時にn
パラメータを指定する必要があります。 alloca
を使用した場合
double operator() (double xx) const
{
auto work = static_cast<double*> (alloca (n * sizeof (double)));
...
いくつかの鐘リング:私はこのような何かについて疑問に思って、私はもちろん、とにかくそれが度100を使用することは非常に愚かだ(オーバーフローするalloca
呼び出しを避けるためにn
上のキャップを持っているつもりです多項式補間)。
しかし私は、アプローチにはかなりunconfortableだ:
- 私は
alloca
のいくつかの明白な危険が足りませんか? - ここでヒープ割り当てを避けるより良い方法はありますか?
Cでこの機能を書いてC99 VLAを使うことはできませんか? –
@KonradRudolph 'double neville(double xx、size_t n、const double * x、const double * y、double * work);' - この関数を書くには演算子のオーバーロードが必要ですか?うわー、私は知らなかった! –
@ H2CO3ヘヒェ、私を捕まえた。さて、私の最後の議論は、CとC++コードのリンクを強く嫌うということです。もちろん、実際には問題はありません(正しく行われれば!そして、私はそれを間違ってしまい、多くの苦痛を与えた多くのCライブラリに遭遇しました)。しかし、その後、私はallocaでVLAを使うことには何のメリットもありませんが、何かが欠けているのでしょうか? –