【问题标题】:What are the optimization levels on D?D 的优化级别是多少?
【发布时间】:2016-07-01 14:30:38
【问题描述】:

dub 在下面构建优化的二进制文件的升序是什么? (例如...调试

$ dub build -h
...
      -b  --build=VALUE     Specifies the type of build to perform. Note that
                            setting the DFLAGS environment variable will override
                            the build type with custom flags.
                            Possible names:
                              debug (default), plain, release, release-debug,
                              release-nobounds, unittest, profile, profile-gc,
                              docs, ddox, cov, unittest-cov and custom types
...

dub build -b release-nobounds 似乎源自dmd -O -release -boundscheck=off,那么dub 与构建fastest executables 的等价物是什么?

【问题讨论】:

    标签: d dub


    【解决方案1】:

    这些选项并不是真正的优化(而且我认为 dub 将它们组合在一起很奇怪,在 dmd 本身上,它们是八个独立的开关......),很多人对它们的意思感到困惑,所以让我列出,使用 dmd 开关名称:

    • -debug 只是在代码中编译 debug 语句,例如debug writeln("foo"); 只会在使用 -debug 编译时写入 foo。它没有做任何其他事情!重要的是,它不包含调试器的信息,这是通过 -g 完成的(尽管 dub 可能会结合这两个选项)。

    • -g 增加了符号调试信息,让gdb 等程序知道函数名。同样的信息也用于异常堆栈跟踪打印,因此启用它会导致堆栈跟踪也显示函数名称。

    • -release 禁用 assert 语句、inoutinvariant 合同,以及 @system 函数中的自动数组边界检查(这是默认的顺便说一句)。就是这样 - 它不会启用优化,也不会暗示与-debug 相反,它只是跳过那些与assert 相关的项目。 (请注意,assert(0); 是一种特殊情况,永远不会被禁用,但无论如何都不应该发生 - 它会杀死程序。)

    • -unittest 将编译unittest 块,并在运行main 之前运行它们(然后main 仍会像往常一样运行)。

    • -profile 在函数前后添加计时信息,并在程序完成时将该信息写入日志文件。请注意,它仅适用于单线程程序,并且其日志记录会显着减慢程序本身的速度。您可以使用它来确定哪些函数被调用最多,哪些函数调用最慢,以了解优化工作的重点。

    • -cov 将信息添加到测试日志中,告诉您程序的哪些行实际运行,哪些没有运行。

    • -profile=gc 执行特定于 GC 的分析,并写出包含时间信息的日志。

    • -D 在编译时从代码中的 ddoc 信息生成 HTML 文件。配音将此称为docsddox 类似,但使用 dub-custom 文档生成器而不是默认的 dmd html 生成器。这是 ddoc 的输出:http://dlang.org/phobos/std_algorithm.html,这是 ddox 的:http://dlang.org/library/std/algorithm.html

    • -boundscheck=xxxx 确定在哪里编译数组边界检查 - 安全函数、所有函数或不编译。 (在旧版本中,这与-release 开关相关联,但现在可以单独完成)。 -release 的默认值为@safe 函数,其他任何地方的默认值为所有函数。

    请注意,其中没有一个是 -O-inline!这些是 dmd 优化开关:-O 表示优化代码,-inline 表示内联函数(它单独执行它们,因为有时内联会弄乱调试器。其他编译器,gdc 和 ldc,将自动与它们的 @987654360 内联@ options 并且通常比 dmd 做得更好。)

    就个人而言,我强烈反对使用-boundscheck-release - 在大多数情况下,它们只是隐藏错误,而不会对最终速度产生太大影响。如果您发现某个紧密循环中的边界检查会减慢您的速度,请不要在整个程序中使用-boundscheck 杀死它,而是在特定的慢速访问上使用.ptr(您可以使用-profile 找出哪个要优化的功能!)在此处了解有关本周提示的更多信息:http://arsdnet.net/this-week-in-d/dec-06.html

    -release 仅在您执行大量昂贵的断言时才会产生显着差异......再说一次,我更愿意单独版本化昂贵的断言而不是禁用所有东西,包括真正常见的快速检查错误。

    所以,我建议只使用-O-inline 以获得优化的 dmd 构建。顺便说一句,对于许多(但不是全部)程序,gdc -Oldc -O 比任何 dmd 开关组合都做得更好 - 如果你的 CPU 有限,你可能也想尝试一下。


    回到配音。查看包格式文档:http://code.dlang.org/package-format?lang=json

    构建类型release,所以dub build -b release-O -release -inline 传递给dmd。键入 release-nobounds 也添加了 nobounds 开关。这就是 dmd 文档所说的最快的可执行文件,我称之为错误的错误。

    据我所知(我自己实际上并没有使用它)最好的配音选项是在配音配置文件(dub.json 或 dub.sdl)中添加buildOptionsoptimize

    这给了你-O,然后你使用.ptr 技术或version 等昂贵的assert 来选择性地加速你的热点,而不会影响程序其余部分的反错误功能。

    在此处阅读更多配音文档:

    http://code.dlang.org/package-format?lang=json#build-options

    【讨论】:

    • 非常感谢您对D的编译和优化策略的透彻分析。
    猜你喜欢
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    相关资源
    最近更新 更多