【问题标题】:GCC function attributes vs cachingGCC 函数属性与缓存
【发布时间】:2009-04-05 14:46:13
【问题描述】:

我有一个代价高昂的函数被多次调用,并且该参数的可能值集非常有限。
函数返回码仅取决于参数,因此加快速度的明显方法是在函数中为可能的参数和相应的返回码保留一个静态缓存,因此对于参数的每种组合,代价高昂的操作将只执行一次。 我总是在这种情况下使用这种方法,它工作得很好,但我突然想到 GCC 函数属性 constpure 可能可以帮助我解决这个问题。

有人有这方面的经验吗? GCC 如何使用 pureconst 属性 - 仅在编译时或运行时使用?
我可以依靠 GCC 足够聪明地调用一个函数,声明为

int foo(int) __attribute__ ((pure))

对于相同的参数值只需一次,或者没有任何保证,我最好坚持缓存方法?

编辑:我的问题不是关于缓存/记忆/查找表,而是 GCC 函数属性。

【问题讨论】:

  • 纯不适用。但 const 看起来不错。

标签: c optimization gcc


【解决方案1】:

我认为您将 GCC 纯属性与 memoization 混淆了。

GCC 纯属性允许编译器减少在某些情况下调用函数的次数(例如循环展开)。但是,它不保证它会这样做,只有在它认为合适的情况下。

您似乎正在寻找的是对您的功能的记忆。记忆是一种优化,不应该重复对相同输入的计算。相反,应该返回先前的结果。 GCC 纯属性不会使函数以这种方式工作。你必须手动实现它。

【讨论】:

  • 好吧,我不知道这个词——记忆,我曾经把它叫做缓存,这就是我已经实现的。我只是希望有其他方法。
  • @qrdl,记忆化是一种非常特殊的缓存形式。我尽可能避免使用行话,因为我不觉得它总能为对话增加价值。在这种情况下,知道这个词确实会增加价值,因为那里有很多记忆库和文章。这是一个有趣的话题。
  • 谢谢,下次我会检查库而不是从头开始编写记忆代码。
  • 请注意,它被称为 memoization,没有字母 r。
【解决方案2】:

我有一个代价高昂的函数被多次调用,并且该参数的可能值集非常有限。

那么为什么不使用静态常量映射(参数'可以散列以生成键,返回码为值)?

【讨论】:

  • 返回值取决于数据库,它在程序运行期间不会改变,但可能会在运行之间改变,所以我需要为每个可能的参数值调用至少一次函数。
  • 嗯。只要数据在一次运行中不发生变化,您仍然可以拥有地图。查找表总是很好。
  • 这就是我所做的,我称之为缓存。 JaredPar 说这叫记忆。
  • @diskgently:我同意,他可以在程序启动时读取数据库的相关部分并创建一个查找表。然后在运行时使用它。
【解决方案3】:

这听起来可以用模板函数解决。如果所有已知参数和返回值在编译时都是已知的,那么您也许可以为每个可能的参数生成函数的模板实例。本质上,您将为每个可能的参数调用函数的不同实例。不确定它是否比您已经实现的静态缓存更容易,但可能值得探索。

查看template metaprogramming。这些概念类似于 JaredPar 建议的“记忆化”,即使使用相同的阶乘函数的介绍性示例。说这些类型的模板是记忆化的编译时实现可能是恰当的。

【讨论】:

  • 参数和返回值在编译时是未知的。但是你能详细说明一下模板功能吗?我从未听说过这种方法。
  • 我在上面添加了一个参考。我没有足够的实践经验来编写适合您问题的示例。它可能对您当前的问题没有用处,但探索 C++ 模板引擎可以做什么肯定很有趣。
  • 我刚刚意识到您可能只使用严格的 C 语言。如果是这种情况,我很抱歉让您分心。
  • @veefu:问题是关于 C 的;模板元编程是 C++。另外,一般来说,模板是用来处理不同类型的,而不是处理同一类型的不同值。
【解决方案4】:

我不喜欢重新打开旧线程,但是这里有一个特别冒犯的评论:

“模板是用来处理不同类型的,而不是处理同一类型的不同值”

现在,采用一个简单的模板阶乘实现:

template<int n> struct Factorial {
    static const int value = n * Factorial<n-1>::value;
};

template<> struct Factorial<0> {
    static const int value = 1;
};

这里的模板参数是一个整数,而不是类型名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多