windows 冷启动与热启动的比较
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/127029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing cold-start to warm start
提问by Motti
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 ClearMemto 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.
大多数(如果不是全部)差异似乎来自加载 DLL,当 DLL 位于缓存内存页面中时,它们的加载速度要快得多。我们尝试使用ClearMem来模拟重新启动(因为它比实际重新启动花费的时间少得多)并得到了不同的结果,在某些机器上它似乎非常一致地模拟重新启动,而在某些机器上则不然。
To sum up my questions are:
总结一下我的问题是:
- Have you experienced differences in launch time between cold and warm starts?
- How have you delt with such differences?
- 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.
- 该应用程序主要是带有一些 .NET 的本机 C++(加载的第一个 .NET 程序集为 CLR 付费)。
- 我们正在寻求改善加载时间,显然我们做了分析并改进了代码中的热点。
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.
我忘记提及的是,我们通过重新构建所有二进制文件获得了一些改进,因此加载程序不必在加载时执行此操作。
采纳答案by Mark
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 wherethe 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.
我不知道有什么工具可以清除磁盘/文件系统缓存,但是您可以编写一个快速应用程序来从磁盘读取一堆不相关的文件,从而使文件系统/磁盘缓存加载不同的信息。
回答by Jim Burger
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.
至于模拟重启,您是否考虑过从虚拟 PC运行您的应用程序?使用虚拟化,您可以方便地一遍又一遍地复制一组条件。
I would also consider some type of profiling appto 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.
我还会考虑某种类型的分析应用程序来发现导致时间滞后的代码位,然后判断该代码中有多少是真正需要的,或者是否可以以不同的方式实现。
回答by Daniel Papasian
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.
在现代机器中,您到处都有内存和缓存:VM 子系统为程序存储内存页面,然后操作系统将文件的内容缓存在内存中,然后您就可以——硬盘驱动器上扇区的磁盘缓冲区。您可能可以重置操作系统缓存,但是驱动器上的磁盘缓冲区呢?我不知道有什么办法。
回答by Motti
@Morten Christiansensaid:
@莫滕克里斯蒂安森说:
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.
例如,Adobe 阅读器使用一种使应用程序冷启动更快(有点)的方法,通过在启动时加载一些文件,从而对用户隐藏冷启动。这仅在程序不应该立即启动时才可用。
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).
这使得客户在每次启动时都要为初始化我们的应用程序付费,即使它没有被使用,我真的不喜欢那个选项(Raymond也不喜欢)。
回答by MSalters
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.
加速应用程序启动的一种成功方法是将 DLL 切换为延迟加载。这是一个低成本的更改(一些摆弄项目设置),但可以显着加快启动速度。之后,在分析模式下运行depends.exe 以确定无论如何在启动期间加载了哪些DLL,并恢复它们的延迟加载。请记住,您还可以延迟加载您需要的大多数 Windows DLL。
回答by stevex
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.
Visual Studio 链接器允许您传入一个文件,其中列出了正在链接的模块中的所有函数(或者只是其中的一些 - 不必是全部),并且链接器会将这些函数彼此相邻放置记忆。
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.
当您的应用程序启动时,通常会在整个应用程序中调用 init 函数。这些调用中的许多将针对尚未在内存中的页面,从而导致页面错误和磁盘搜索。这就是启动缓慢的由来。
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.
查看 Visual Studio 2005 或更高版本中的 Profile Guided Optimization。PGO 为您做的一件事是功能链接排序。
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.
在构建过程中工作有点困难,因为使用 PGO,您需要链接、运行您的应用程序,然后与配置文件运行的输出重新链接。这意味着您的构建过程需要有一个运行时环境并在错误构建之后进行清理等等,但回报通常是 10+ 或更快的冷启动,无需更改代码。
There's some more info on PGO here:
这里有更多关于 PGO 的信息:
回答by Baiyan Huang
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.
我不确定函数顺序列表是否也可以指定全局变量,但使用这个 #pragma data_seg 就可以了。
回答by Baiyan Huang
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)
如果您的应用程序不是很复杂,您可以将所有可执行文件复制到另一个目录,这应该类似于重新启动。(剪切和粘贴似乎不起作用,Windows 足够聪明,知道移动到另一个文件夹的文件已缓存在内存中)
回答by Morten Christiansen
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.
例如,Adobe 阅读器使用一种使应用程序冷启动更快(有点)的方法,通过在启动时加载一些文件,从而对用户隐藏冷启动。这仅在程序不应该立即启动时才可用。
Another note, is that .NET 3.5SP1 supposedly has much improved cold-start speed, though how much, I cannot say.
另一个注意事项是,.NET 3.5SP1 据说已经大大提高了冷启动速度,但具体多少,我不能说。
回答by Jay
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.
它可能是 NIC(LAN 卡),并且您的应用程序依赖于需要网络启动的某些其他服务。因此,单独分析您的应用程序可能无法完全告诉您这一点,但您应该检查应用程序的依赖项。