【问题标题】:When to use restrict and when not to何时使用限制,何时不使用
【发布时间】:2010-10-24 09:28:44
【问题描述】:

我对@9​​87654321@ 有一个大致的了解,但我希望能澄清一些要点。我有一个函数,它从一个缓冲区读取一个以空字符结尾的字符串,并在另一个缓冲区中写出一个 URL 编码版本。该函数有这个签名(目前没有restrict):

char const *StringUrlEncode(char const *unencoded, 
                            char *encoded,
                            char *encodedEnd);

unencoded 是我的以 null 结尾的源字符串。目标缓冲区由encodedencodedEnd表示,其中encoded指向缓冲区中的第一个charencodedEnd指向缓冲区之后的第一个字符,即函数将写入chars,但不包括encodedEnd 指向的位置——如果你熟悉 C++ STL,这是基本的begin/end 迭代器对约定。

如果我在这个函数中添加restrict,它应该只应用于前两个参数吗:

char const *StringUrlEncode(char const *restrict unencoded, 
                            char *restrict encoded,
                            char *encodedEnd);

或者将它添加到所有三个参数中是否有一些我不理解的好处?

我可以看到使输入和输出缓冲区restrict 有助于编译器知道它们不重叠。但是由于最后一个参数encodedEnd 仅用于标记输出缓冲区的结束,我认为restrict 对这里的编译器没有任何帮助(尽管我认为它不会伤害,除了在函数声明中添加不必要的噪音)。

【问题讨论】:

    标签: c pointers c99 restrict-qualifier


    【解决方案1】:

    试试 Mike Acton 的文章 here (old link)。限制是可怕的,因为不使用它会影响性能,也因为使用不当会造成后果。

    在您的情况下,听起来您可以安全地对所有三个指针应用限制,因为没有别名相同的内存区域。但是,在第三个指针上使用它几乎没有性能优势。

    【讨论】:

    • 我已经阅读了 Mike 的文章(现在两次),这是一个好的开始,但给我留下了一些问题 :-)
    • 给定的链接无效。谷歌建议在cellperformance.beyond3d.com/articles/2006/05/…(2009-09-06 验证)有一个更新版本,但这也带来了问题。缓存版本可在 Google 上获得。
    【解决方案2】:

    在这种特殊情况下,无论 encodedEnd 是否为限制,都不会产生影响;您已向编译器承诺,没有人为 unencodedencoded 起别名,因此读取和写入不会相互干扰。

    在这种情况下,restrict 很重要的真正原因是,没有它,编译器无法知道通过 encoded 进行的写入不会影响通过 unencoded 进行的读取。例如,如果

    encoded == unencoded+1
    

    那么每次写入encoded都会影响后续每次读取unencoded,因此编译器在写入完成之前无法调度加载。 restrict 向编译器承诺这两个指针不会影响相同的内存,因此它可以将加载安排得足够远以避免管道停顿。

    【讨论】:

      【解决方案3】:

      我认为你是对的,它不会受到伤害。您的循环指针(称为 p)将在循环结束时等于 encodedEnd。但是在循环之后(从 p 或 encodedEnd)不需要访问任何内容,所以这应该不是问题。我认为它也无济于事,因为从未从 encodedEnd 写入或读取任何内容,因此没有什么可以优化的。

      但我同意你的前两个限制应该真的有帮助。

      【讨论】:

      • 请注意,取消引用 encryptedEnd 是未定义的行为,因为编码也是限制 - 所以实际上,编码结束是否限制并不重要。
      猜你喜欢
      • 2014-04-21
      • 2013-09-08
      • 1970-01-01
      • 1970-01-01
      • 2010-10-15
      • 2013-03-12
      • 2012-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多