【问题标题】:How do demomakers attain ultra small filesizes?演示制作者如何获得超小文件大小?
【发布时间】:2014-03-07 01:11:44
【问题描述】:

当我在 youtube 上观看演示场景视频时,作者经常吹嘘他们的文件大小是 64kb 或更小,有些只有 4kb。当我用 C++ 编译一个非常基本的程序时,可执行文件总是至少 90kb 左右。这些演示完全是用汇编编写的吗?据我了解,demomakers 也使用了 c/c++。

【问题讨论】:

  • 是的,你基本上是对的。秘密成分是先进的.exe 压缩器,以及它们在减小文件大小的过程中采用的技巧。其中许多(全部?)都与特定的编译器(主要是 MSVC)相关联。这里没有模板。
  • 一切尽在您的链接中,您可以使用 C/C++ 来完成这项工作。
  • 如果你不使用任何库函数,你也可以通过编译器实现相当小的文件大小。但是,一旦您链接到您的第一个printf,您就会被敬酒。 :) 当然,低于某个最小值需要组装。
  • 你称之为超小?我记得看过 64 字节的演示(.com 文件,通过单字节 RET 退出,甚至不是传统的 2 字节 INT 20)。诚然,他们没有做太多。

标签: c++ assembly filesize code-size demoscene


【解决方案1】:

我是Felix's WorkshopImmersion 的编码员之一(64k intros by Ctrl-Alt-Test)。现在大多数 64k 介绍都使用 C++(例外:Logicoma 使用 Rust)。汇编可能对 4k intros 有意义(尽管它们中的大多数实际上使用 C++),但不适用于 64k intros。

以下是最重要的两件事:

  • 不使用标准库进行编译(特别是,STL 会使二进制文件变得非常大)。
  • 压缩您的二进制文件(kkrunchy 用于 Windows 上的 64k intros,Crinkler 用于 Windows 上的 4k intros)。

现在,您可以在填充 64kB 之前编写大量代码。如何使用它们?程序生成。

  • 对于音乐,音乐表被压缩。乐器是用软合成器生成的。一个流行的选项,虽然有点过时,是使用v2 by Farbrausch
  • 如果您需要纹理,请生成它们。
  • 如果您需要 3d 模型,请生成它们。
  • 动画和效果是程序性的。
  • 对于相机,保存一些关键位置并进行插值。
  • 现代图形中大量使用着色器。 Minifying the shaders 可以节省不少空间。

想了解更多有关程序生成和其他技术的信息吗?检查IQ's articles

如果你想进一步优化你的代码,这里有一些额外的技巧:

  • 您可能使用了很多浮点数。试试truncate the mantissa of your floats(可以节省很多kB)。
  • 禁用函数内联(它为我节省了 2kB)。
  • 试试 fastcall 调用约定(它为我节省了 0.7kB)。
  • 禁用对异常的支持。你不需要它们。
  • 如果您使用类,请避免继承。
  • 使用模板时要小心。

在典型的 4k 介绍中,C++ 代码用于音乐和初始化。图形在着色器中完成。

【讨论】:

    【解决方案2】:

    这真的取决于你的环境,但如果你不这样做 实例化任何模板,然后动态链接所有内容, 为您实现非常小的尺寸是相当容易的 可执行文件,因为您实际执行的代码都不是 在可执行文件中。

    【讨论】:

      【解决方案3】:

      我还不能发表评论,因为我没有 50 个代表点,所以我正在回答。

      创建较小程序的一种方法是使用较旧的编译器,例如 Microsoft Visual C/C++ 4.0,它生成的 .exe 文件比 Microsoft Visual Studio 2005 更小。

      【讨论】:

        【解决方案4】:

        这些演示不使用标准库(不是 C++,甚至不是 C 标准库),也没有与标准库链接(以避免导入表大小)。它们仅动态链接必要的绝对最小值。
        演示的“主函数”通常与入口点相同(不像在普通程序中,入口点是 CRT 初始化函数,它执行一些特定于操作系统的设置、初始化全局变量、运行构造函数并最终调用 main)。

        通常演示可执行文件不符合可执行格式的规范(省略最小节大小和对齐方式),并使用 exe 打包程序进行压缩。从技术上讲,这些是“损坏”的程序,但它们只是被“损坏”到如此之多,以至于它们仍然可以成功运行。

        此外,此类演示严重依赖程序生成的内容。

        【讨论】:

        • “它们只动态链接必要的绝对最小值。”:我认为您的意思是“静态地”
        • @JulienGuertault:不,他们根本不会静态链接任何东西,这太令人生畏了。它们动态链接,但绝对是最低限度。 IAT/thunk 占用空间,因此您希望尽可能少,即使这意味着程序不符合标准(只要它在不崩溃和生成图像/动画的意义上“工作”,那很好)。
        • 你别无选择:如果你想制作一个win32程序,你需要静态链接几个库,如果你也想使用OpenGL。诀窍是尽可能少地链接它们(通过重写你需要的东西,例如 CRT),并尽可能少地使用链接的那些,同时积极地删除不使用的代码。虽然其中一些库在幕后执行动态链接系统 DLL,但无论如何,这大约是竞争规则所允许的范围。
        【解决方案5】:

        这些超小型程序通常不依赖于任何库或框架,这在传统应用程序开发中很常见。这些程序通常直接访问graphics/io等。

        【讨论】:

        • 好吧,你错了。 Windows 演示使用OpenGLDirectX
        • @user1095108 但是 OpenGl/DirectX 代码驻留在 DLL 中,而不是必须链接的库中(因此会增加文件大小)
        • 您写道“通常不依赖于任何库或框架”,DLL 代表动态链接库。如果您不相信我,请检查此en.wikipedia.org/wiki/Dynamic-link_library
        • @user1095108:好的,好的,当我写“库”时,我的意思是一个静态链接的 .lib 文件。除了调用其函数的代码之外,DLL 不会增加使用它的程序的大小。
        • @user1095108 这是“调用其函数的代码”的一部分——与 DLL 的大小相比,这是微不足道的字节数
        猜你喜欢
        • 1970-01-01
        • 2013-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-07
        • 1970-01-01
        • 2023-04-11
        相关资源
        最近更新 更多