D 的优化级别是多少?

What are the optimization levels on D?

下面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 的等价物是什么?

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

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

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

  • -release 禁用 assert 语句、inoutinvariant 契约,并在 @system 函数(这是默认的 btw)。就是这样 - 它既不启用优化也不暗示 -debug 的反面,它只是跳过那些 assert 相关的项目。 (请注意 assert(0); 是一种特殊情况,永远不会被禁用,但无论如何它都不应该发生 - 它会杀死程序。)

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

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

  • -cov 向测试日志添加信息,告诉您程序的哪些行实际上是 运行,哪些不是。

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

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

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

请注意,其中 NONE 是 -O-inline!这些是 dmd 优化开关:-O 表示优化代码,-inline 表示内联函数(它单独执行它们,因为有时内联会弄乱调试器。其他编译器 gdc 和 ldc 将自动内联使用他们的 -O 选项,并且通常比 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。 Type release-nobounds 也添加了 nobounds 开关。这就是 dmd 文档所说的最快的可执行文件,我称之为错误。

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

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

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

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