冷启动与热启动的比较

发布于 2024-07-05 05:50:59 字数 617 浏览 8 评论 0原文

我们的应用程序在重新启动(冷启动)后启动所需的时间比已经打开一次(热启动)要多得多。

大多数(如果不是全部)差异似乎来自加载 DLL,当 DLL 位于缓存内存页面中时,它们加载速度要快得多。 我们尝试使用 ClearMem 来模拟重新启动(因为它比实际重新启动花费的时间要少得多)并得到了不同的结果,在某些机器上,它似乎非常一致地模拟重新启动,而在某些机器上则不然。

总结一下我的问题是:

  1. 您是否经历过冷启动和热启动之间的启动时间差异?
  2. 您是如何应对这些差异的?
  3. 您知道一种可靠地模拟重新启动的方法吗?

编辑:

注释说明:

  • 该应用程序主要是本机 C++ 和一些 .NET(加载的第一个 .NET 程序集为 CLR 付费)。
  • 我们希望缩短加载时间,显然我们已经进行了分析并改进了代码中的热点。

我忘记提到的是,我们通过重新设置所有二进制文件的基础来获得一些改进,这样加载器就不必在加载时执行此操作。

Our application takes significantly more time to launch after a reboot (cold start) than if it was already opened once (warm start).

Most (if not all) the difference seems to come from loading DLLs, when the DLLs' are in cached memory pages they load much faster. We tried using ClearMem to simulate rebooting (since its much less time consuming than actually rebooting) and got mixed results, on some machines it seemed to simulate a reboot very consistently and in some not.

To sum up my questions are:

  1. Have you experienced differences in launch time between cold and warm starts?
  2. How have you delt with such differences?
  3. Do you know of a way to dependably simulate a reboot?

Edit:

Clarifications for comments:

  • The application is mostly native C++ with some .NET (the first .NET assembly that's loaded pays for the CLR).
  • We're looking to improve load time, obviously we did our share of profiling and improved the hotspots in our code.

Something I forgot to mention was that we got some improvement by re-basing all our binaries so the loader doesn't have to do it at load time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

傾城如夢未必闌珊 2024-07-12 05:50:59

@莫滕·克里斯蒂安森 说:

Adobe Reader 等公司使用一种使应用程序更快地启动冷启动的方法,即在启动时加载一些文件,从而对用户隐藏冷启动。 仅当程序不应该立即启动时才可用。

这使得客户在每次启动时都要为初始化我们的应用程序付费,即使它没有使用,我真的不喜欢这个选项(雷蒙德)。

@Morten Christiansen said:

One way to make apps start cold-start faster (sort of) is used by e.g. Adobe reader, by loading some of the files on startup, thereby hiding the cold start from the users. This is only usable if the program is not supposed to start up immediately.

That makes the customer pay for initializing our app at every boot even when it isn't used, I really don't like that option (neither does Raymond).

⒈起吃苦の倖褔 2024-07-12 05:50:59

作为函数顺序列表的替代方案,只需将要在同一部分中调用的代码分组即可:

#pragma code_seg(".startUp")
 //...
#pragma code_seg

#pragma data_seg(".startUp")
 //...
#pragma data_seg

随着代码的更改,它应该很容易维护,但具有与函数顺序列表相同的优点。

我不确定函数 order list 是否也可以指定全局变量,但使用这个 #pragma data_seg 就可以了。

As an alternative to function order list, just group the code that will be called within the same sections:

#pragma code_seg(".startUp")
 //...
#pragma code_seg

#pragma data_seg(".startUp")
 //...
#pragma data_seg

It should be easy to maintain as your code changes, but has the same benefit as the function order list.

I am not sure whether function order list can specify global variables as well, but use this #pragma data_seg would simply work.

黎夕旧梦 2024-07-12 05:50:59

例如,Adobe reader 使用一种使应用程序冷启动更快(某种程度上)的方法,即在启动时加载一些文件,从而对用户隐藏冷启动。 仅当程序不应该立即启动时才可用。

另一个注意事项是,.NET 3.5SP1 据称大大提高了冷启动速度,但具体提高了多少,我不能说。

One way to make apps start cold-start faster (sort of) is used by e.g. Adobe reader, by loading some of the files on startup, thereby hiding the cold start from the users. This is only usable if the program is not supposed to start up immediately.

Another note, is that .NET 3.5SP1 supposedly has much improved cold-start speed, though how much, I cannot say.

尴尬癌患者 2024-07-12 05:50:59

它可能是 NIC(LAN 卡),并且您的应用程序依赖于某些其他
需要网络启动的服务。 因此,单独分析您的应用程序可能无法完全告诉您这一点,但您应该检查应用程序的依赖关系。

It could be the NICs (LAN Cards) and that your app depends on certain other
services that require the network to come up. So profiling your application alone may not quite tell you this, but you should examine the dependencies for your application.

复古式 2024-07-12 05:50:59

改善应用程序冷启动时间的一个非常有效的技术是优化函数链接排序。

Visual Studio 链接器允许您传入一个文件,其中列出了正在链接的模块中的所有函数(或只是其中一些 - 不一定是全部),并且链接器会将这些函数彼此相邻地放置在记忆。

当您的应用程序启动时,通常会在整个应用程序中调用 init 函数。 其中许多调用将针对尚未在内存中的页面,从而导致页面错误和磁盘寻道。 这就是启动缓慢的原因。

优化您的应用程序,将所有这些功能结合在一起可能是一个巨大的胜利。

查看 Visual Studio 2005 或更高版本中的配置文件引导优化。 PGO 为您做的一件事是函数链接排序。

构建过程有点困难,因为使用 PGO,您需要链接、运行应用程序,然后重新链接配置文件运行的输出。 这意味着您的构建过程需要有一个运行时环境,并在错误构建后进行清理等等,但回报通常是在不更改代码的情况下冷启动速度提高 10+ 或更多。

这里有一些关于 PGO 的更多信息:

http://msdn.microsoft.com/ en-us/library/e7k32f4k.aspx

A very effective technique for improving application cold launch time is optimizing function link ordering.

The Visual Studio linker lets you pass in a file lists all the functions in the module being linked (or just some of them - it doesn't have to be all of them), and the linker will place those functions next to each other in memory.

When your application is starting up, there are typically calls to init functions throughout your application. Many of these calls will be to a page that isn't in memory yet, resulting in a page fault and a disk seek. That's where slow startup comes from.

Optimizing your application so all these functions are together can be a big win.

Check out Profile Guided Optimization in Visual Studio 2005 or later. One of the thing sthat PGO does for you is function link ordering.

It's a bit difficult to work into a build process, because with PGO you need to link, run your application, and then re-link with the output from the profile run. This means your build process needs to have a runtime environment and deal cleaning up after bad builds and all that, but the payoff is typically 10+ or more faster cold launch with no code changes.

There's some more info on PGO here:

http://msdn.microsoft.com/en-us/library/e7k32f4k.aspx

寄风 2024-07-12 05:50:59

加速应用程序启动的一种成功方法是将 DLL 切换为延迟加载。 这是一个低成本的更改(一些项目设置的修改),但可以使启动速度显着加快。 然后,在分析模式下运行depends.exe,以找出启动期间加载的DLL,并恢复它们的延迟加载。 请记住,您还可以延迟加载所需的大多数 Windows DLL。

One succesful way to speed up application startup is to switch DLLs to delay-load. This is a low-cost change (some fiddling with project settings) but can make startup significantly faster. Afterwards, run depends.exe in profiling mode to figure out which DLLs load during startup anyway, and revert the delay-load on them. Remember that you may also delay-load most Windows DLLs you need.

放赐 2024-07-12 05:50:59

如果您的应用程序不是很复杂,您可以将所有可执行文件复制到另一个目录,这应该类似于重新启动。 (剪切和粘贴似乎不起作用,Windows足够聪明,知道移动到另一个文件夹的文件会缓存在内存中)

If your application is not very complicated, you can just copy all the executables to another directory, it should be similar to a reboot. (Cut and Paste seems not work, Windows is smart enough to know the files move to another folder is cached in the memory)

半仙 2024-07-12 05:50:59

您如何分析您的代码? 并非所有分析方法都是相同的,有些方法比其他方法更能找到热点。 您正在加载大量文件吗? 如果是这样,磁盘碎片和寻道时间可能会发挥作用。

也许甚至将基本的计时信息粘贴到代码中、写入日志文件并在冷/热启动时检查文件将有助于识别应用程序在哪里花费时间。

如果没有更多信息,我会倾向于文件系统/磁盘缓存作为两种环境之间可能的差异。 如果是这种情况,那么您要么需要花更少的时间预先加载文件,要么找到更快的方法来加载文件。

示例:如果您要加载大量二进制数据文件,请通过将它们组合成一个文件来加快加载速度,然后一次读取将整个文件放入内存并解析其内容。 更少的磁盘寻道和从磁盘读取数据所花费的时间。 再说一次,也许这并不适用。

我不知道有什么工具可以清除磁盘/文件系统缓存,但是您可以编写一个快速应用程序来从磁盘读取一堆不相关的文件,从而导致文件系统/磁盘缓存加载不同的信息。

How did you profile your code? Not all profiling methods are equal and some find hotspots better than others. Are you loading lots of files? If so, disk fragmentation and seek time might come into play.

Maybe even sticking basic timing information into the code, writing out to a log file and examining the files on cold/warm start will help identify where the app is spending time.

Without more information, I would lean towards filesystem/disk cache as the likely difference between the two environments. If that's the case, then you either need to spend less time loading files upfront, or find faster ways to load files.

Example: if you are loading lots of binary data files, speed up loading by combining them into a single file, then do a slerp of the whole file into memory in one read and parse their contents. Less disk seeks and time spend reading off of disk. Again, maybe that doesn't apply.

I don't know offhand of any tools to clear the disk/filesystem cache, but you could write a quick application to read a bunch of unrelated files off of disk to cause the filesystem/disk cache to be loaded with different info.

千笙结 2024-07-12 05:50:59

很难在软件中真正模拟重新启动。 当您重新启动时,计算机中的所有设备都会声明其重置位,这将导致系统范围内的所有内存丢失。

在现代机器中,内存和缓存无处不在:VM 子系统为程序存储内存页面,然后操作系统在内存中缓存文件内容,然后您就可以了硬盘本身扇区的磁盘缓冲区。 您可能可以重置操作系统缓存,但是驱动器上的磁盘缓冲区呢? 我不知道有什么办法。

It would be hard to truly simulate a reboot in software. When you reboot, all devices in your machine get their reset bit asserted, which should cause all memory system-wide to be lost.

In a modern machine you've got memory and caches everywhere: there's the VM subsystem which is storing pages of memory for the program, then you've got the OS caching the contents of files in memory, then you've got the on-disk buffer of sectors on the harddrive itself. You can probably get the OS caches to be reset, but the on-disk buffer on the drive? I don't know of a way.

贪了杯 2024-07-12 05:50:59

至于模拟重新启动,您是否考虑过从虚拟 PC 运行您的应用程序? 使用虚拟化,您可以方便地一遍又一遍地复制一组条件。

我还会考虑某种类型的分析应用程序来发现导致时间滞后的代码位,并且然后判断该代码中有多少是真正必要的,或者是否可以通过不同的方式实现。

As for simulating reboots, have you considered running your app from a virtual PC? Using virtualization you can conveniently replicate a set of conditions over and over again.

I would also consider some type of profiling app to spot the bit of code causing the time lag, and then making the judgement call about how much of that code is really necessary, or if it could be achieved in a different way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文