查找表与运行时计算效率 - C ++

时间:2013-03-16 17:40:33

标签: c++ performance caching optimization lookup-tables

我的代码需要不断计算以下函数的值:

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

分析表明程序的这一部分是大部分时间花在的地方。由于程序将运行数周(如果不是几个月),我想优化此操作并考虑使用查找表。

我知道查找表的效率取决于表本身的大小以及它的设计方式。目前我不能使用不到100 MB,最多可以使用2GB。矩阵中两点之间的值将进行线性插值。

使用查找表会比执行计算更快吗?另外,使用N维矩阵会比1-D std :: vector更好吗?不应该越过表格大小的阈值(如果有的话)是什么?

1 个答案:

答案 0 :(得分:4)

  

我正在编写一个不断需要从特定函数计算值的代码。经过一些分析后,我发现我的程序的这一部分是大部分时间花在的地方。

     

到目前为止,我不允许使用少于100 MB,我可以使用高达2GB。线性插值将用于矩阵中各点之间的点。

如果你有巨大的查找表(如你所说的数百MB),这不适合缓存 - 很可能内存查找时间远远高于计算本身。 RAM“非常慢”,尤其是从大型阵列的随机位置获取时。

这是综合测试:

live demo

#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