使用模板构建静态(但复杂)的查找表

时间:2011-01-15 17:49:33

标签: c++ templates optimization compilation lookup

我目前正在优化数值分析代码。在代码中,有一个200x150元素的查找表(当前是静态std::vector <std::vector<double>>),它在每次运行开始时构建。查找表的构造实际上非常复杂 - 查找表中的值是使用迭代割线方法在一组复杂的方程上构造的。目前,对于模拟,查找表的构造是运行时间的20%(运行时间大约为25秒,查找表构造需要5秒)。虽然5秒可能看起来不是很多,但在运行我们的MC模拟时,我们运行50k +模拟,它突然变成了很长一段时间。

除了其他一些想法,还有一件事已经浮出水面 - 我们可以在编译时使用模板构建这个查找表吗?表本身永远不会改变。硬编码大型数组不是一个可维护的解决方案(生成表的方程式不断被调整),但似乎如果表可以在编译时生成,它将给我们两全其美(易于维护,运行期间无开销)。

因此,我提出以下(简化)方案。假设您想在编译时生成一个静态数组(使用最适合您的容器 - 2D c数组,向量矢量等)。你有一个定义的函数 -

double  f(int row, int col);

其中返回值是表中的条目,row是查找表行,col是查找表列。是否可以在编译时使用模板生成此静态数组,以及如何生成?

5 个答案:

答案 0 :(得分:4)

通常最好的解决方案是代码生成。在那里你拥有所有的自由,你可以确定输出实际上是double[][]

答案 1 :(得分:1)

第一次运行程序时将表保存在磁盘上,只有在程序丢失时才重新生成,否则从缓存中加载。

在文件中包含一个版本字符串,以便在代码更改时重新生成。

答案 2 :(得分:1)

这里有几件事。

  1. 您想要做的几乎肯定是至少部分可行的。

  2. 浮点值是无效的模板参数(只是,不要问为什么)。虽然您可以使用N1 / N2表示在模板中表示有理数,但是您可以对它们执行的数学量不包含可以对有理数进行的整个集。例如,root(n)不可用(参见root(2))。除非您想要实现静态双变量的实例化,否则您希望value访问器成为一个函数。 (也许你可以想出一个新的模板浮点表示法,它可以拆分exp和mant然后你就像双重类型一样......玩得开心:P)

  3. 元编程代码很难以清晰的方式格式化。此外,就其本质而言,阅读起来相当困难。即使是专家也很难分析他们没有写的TMP代码,即使它很简单。

  4. 如果实习生或任何高级人员甚至认为只是看着TMP代码,他们的头就会爆炸。虽然,有时候高级开发者会因为他们对新事物感到害怕而大声爆炸(让你的老板觉得无能,但即使不应该这样做也会产生严重后果)。

  5. 所有这些......模板是图灵完整的语言。你可以用它们做“任何事情”......任何事情我们指的是任何不需要某种外部能力的东西,比如系统访问(因为你不能让编译器产生新的线程)。你可以建立你的表。你需要回答的问题是你是否真的想要。

答案 3 :(得分:0)

为什么没有单独的程序?生成表并将其存储在文件中的表,以及加载文件并在其上运行模拟的表。这样,当你需要调整生成表的方程时,你只需要重新编译该程序。

答案 4 :(得分:0)

如果你的桌子是一堆整数,那么是的,你可以。也许。但你当然不能做的是在编译时生成双精度数。

更重要的是,我认为普通的double [] []会比这里的向量向量更好 - 你正在为一个静态大小的表推动大量的动态分配。