3

ダイナミック リンク ライブラリ(DLL)のパフォーマンスを改善したいと考えています。

そのために、 cos()sin()のルックアップ テーブルを使用したいと考えています。

最大のパフォーマンスが必要なので、cos と sin の計算結果を含む0 から 2PIまでのテーブルを作成したいと考えています。

精度の点で良い結果を得るには、関数ごとに 1 mb のテーブルがサイズと精度の間の良いトレードだと思います。

外部ファイルを使用せずにこれらのテーブルを作成および使用する方法を知りたい (DLL であるため) :すべてを 1 つのファイル内に保持したい。

また、プラグインの開始時に sin 関数と cos 関数を計算したくありません。一度計算して標準ベクトルに入れる必要があります。

しかし、C++ でそれを行うにはどうすればよいでしょうか。

EDIT1: jons34yp のコードは、ベクター ファイルを作成するのに非常に適しています。

小さなベンチマークを行ったところ、優れた精度と優れた速度が必要な場合は、250000 単位のベクトルを実行し、それらの間で線形補間を行うと、7.89E-11 の最大エラー (!) が発生し、すべての近似値の中で最速であることがわかりました。私は試しました(そして、sin()よりも12倍以上高速です(正確には13,296倍高速です)

4

3 に答える 3

3

.cc最も簡単な解決策は、ベクターの定義を含むファイルを作成する別のプログラムを作成することです。

例えば:

#include <iostream>
#include <cmath>

int main()
{
    std::ofstream out("values.cc");

    out << "#include \"static_values.h\"\n"; 
    out << "#include <vector>\n";

    out << "std::vector<float> pi_values = {\n";
    out << std::precision(10);

    // We only need to compute the range from 0 to PI/2, and use trigonometric
    // transformations for values outside this range.
    double range = 3.141529 / 2;
    unsigned num_results = 250000;

    for (unsigned i = 0; i < num_results; i++) {
        double value = (range / num_results) * i;
        double res = std::sin(value);

        out << "    " << res << ",\n";
    }
    out << "};\n"
    out.close();
}

このサイズのテーブルはおそらく L2 キャッシュに収まらないため、これによってパフォーマンスが向上する可能性は低いことに注意してください。これは、三角法の計算の大部分が RAM にアクセスする必要があることを意味します。このようなアクセスごとに、およそ数百 CPU サイクルのコストがかかります。

ところで、おおよその SSE SIMD 三角関数ライブラリを見たことがありますか。これは彼らにとって良いユースケースのようです。

于 2013-08-30T11:34:40.930 に答える