查找表VS运行时的计算效率 - C ++(lookup table vs runtime comp

2019-10-17 19:53发布

我的代码需要不断地计算从下面的函数值:

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

剖析表明,这部分程序是大部分的时间都花在。 由于该方案将数周甚至数月跑,我想优化这个操作并正在考虑使用一个查找表。

我知道,一个查找表的效率依赖于表本身的大小,在路上,它的设计。 目前我不能使用小于100 MB,并且可以使用高达2GB。 在矩阵中两个点之间的值,线性插值。

将使用查找表比做计算更快? 此外,将使用N维矩阵是除了1-d的std ::矢量更好的,哪些是不应该越过所述表的大小的阈值(如果有的话)?

Answer 1:

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

到目前为止,我不能使用小于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


文章来源: lookup table vs runtime computation efficiency - C++