1

私のコードでは、次の関数から値を継続的に計算する必要があります。

inline double f (double x) {
    return ( tanh( 3*(5-x)  ) *0.5 + 0.5);
}

プロファイリングは、プログラムのこの部分がほとんどの時間を費やしている場所であることを示しています。プログラムは数か月ではなくても数週間実行されるため、この操作を最適化し、ルックアップテーブルの使用を検討しています。

ルックアップテーブルの効率は、テーブル自体のサイズと、テーブルの設計方法に依存することを私は知っています。現在、100 MB未満は使用できず、2GBまで使用できます。行列の2点間の値は、線形補間されます。

ルックアップテーブルを使用すると、計算を実行するよりも高速になりますか?また、N次元マトリックスを使用する方が1-D std :: vectorよりも優れているでしょうか。また、超えてはならないテーブルのサイズのしきい値(ある場合)はどれくらいですか。

4

1 に答える 1

5

特定の関数から値を計算する必要があるコードを書いています。いくつかのプロファイリングの後、私のプログラムのこの部分がほとんどの時間を費やしている場所であることに気づきました。

これまでのところ、100 MB未満の使用は許可されておらず、最大2GBまで使用できます。線形補間は、マトリックス内のポイント間のポイントに使用されます。

キャッシュに適合しない巨大なルックアップテーブル(あなたが言ったように数百MB)がある場合、おそらくメモリルックアップ時間は計算自体よりもはるかに長くなります。RAMは、特に巨大な配列のランダムな場所からフェッチする場合、「非常に遅い」です。

合成テストは次のとおりです。

ライブデモ

#include <boost/progress.hpp>
#include <iostream>
#include <ostream>
#include <vector>
#include <cmath>

using namespace boost;
using namespace std;

inline double calc(double x)
{
    return ( tanh( 3*(5-x)  ) *0.5 + 0.5);
}

template<typename F>
void test(F &&f)
{
   progress_timer t;
   volatile double res;
   for(unsigned i=0;i!=1<<26;++i)
      res = f(i);
   (void)res;
}

int main()
{
   const unsigned size = (1 << 26) + 1;
   vector<double> table(size);
   cout << "table size is " << 1.0*sizeof(double)*size/(1 << 20) << "MiB" << endl;
   cout << "calc ";
   test(calc);
   cout << "dummy lookup ";
   test([&](unsigned i){return table[(i << 12)%size];}); // dummy lookup, not real values
}

私のマシンの出力は次のとおりです。

table size is 512MiB
calc 0.52 s

dummy lookup 0.92 s
于 2013-03-16T18:30:13.493 に答える