gpt4 book ai didi

d - D 中的 assert()、优化和 assume() 指令

转载 作者:行者123 更新时间:2023-12-01 23:29:17 24 4
gpt4 key购买 nike

假设我有一个 assert() 之类的东西 assert( x < limit );我使用以下代码片段查看了 GDC 中优化器在发布和调试版本中的行为:

uint cxx1( uint x )
{
assert( x < 10 );
return x % 10;
}

uint cxx1a( uint x )
in { assert( x < 10 ); }
body
{
return x % 10;
}

uint cxx2( uint x )
{
if ( !( x < 10 ))
assert(0);
return x % 10;
}

现在,当我在 Debug模式下构建时,断言具有触发巨大优化的非常令人愉悦的效果。 GDC 完全摆脱了执行模运算的可怕代码,因为它知道断言的 if 条件导致的 x 的可能范围。但在 Release模式下,if 条件被丢弃,所以突然间,可怕的代码又回来了,cxx1() 甚至 cxx1a() 中都不再有任何优化。这非常具有讽刺意味, Release模式生成的代码比调试代码差得多。当然,没有人希望属于 if 测试的可执行代码出现在发布代码中,因为我们必须失去所有这些开销。

现在理想情况下,我想在与编译器通信信息的意义上表达条件,无论发布/调试版本如何,关于可能始终假定为真的条件,因此此类假设可以非常指导优化强大的方法。

我相信一些 C++ 编译器有一些叫做 __assume() 或类似的东西,但我在这里记不住了。 GCC 有一个 __builtin_unreachable() 特殊指令,可用于构建 assume() 功能。基本上,如果我可以构建自己的 assume() 指令,它将产生断言关于已知值或已知范围的某些事实并将它们公开/发布到优化过程的效果,而不管发布/ Debug模式如何,但根本不会为在发布版本中假设 () 条件,而在 Debug模式下它与 assert() 完全相同。

我尝试了一个你在 cxx2 中看到的实验,它总是触发优化,在那里做得很好,但即使在带有测试和条件的 Release模式下,它也会为 assume() 的 if 条件生成道德调试代码跳转到未定义的指令以停止进程。

有人知道这是否可以解决吗?或者您认为这是一个有用的 D 编译器幻想愿望 list 项目?

最佳答案

据我所知,__builtin_unreachable 是 GCC 中 assume 类函数的下一个最佳替代品。在某些情况下,if 条件可能仍未得到优化:"Assume" clause in gcc

通过导入 gcc.builtins,可以在 GDC 中使用 GCC 内置函数。下面是一个如何包装 __builtin_unreachable 函数的示例:

import gcc.builtins;

void assume()(bool condition)
{
if (!condition)
__builtin_unreachable();
}

bool foo(int a)
{
assume(a > 10);
return a > 10;
}

这里有两个有趣的细节:

  1. 我们不需要字符串混合或类似的复杂东西。只要你用-O编译,GDC无论如何都会完全优化函数调用。
  2. 要使其正常工作,assume 函数必须内联。不幸的是,当 assume 与调用函数位于不同的模块中时,不完全支持内联普通函数。作为解决方法,我们使用带有 0 个模板参数的模板。这应确保内联始终有效。

您可以在此处测试和修改此示例: explore.dgnu.org

现在我们(GDC 开发人员)可以在 Release模式下轻松地将 assert(...) 重写为 if(...) __builtin_unreachable()。但这可能会破坏一些代码,因此 dmd 应该首先实现它。

关于d - D 中的 assert()、优化和 assume() 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42147707/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com