Вопрос

Нашему приложению требуется значительно больше времени для запуска после перезагрузки (холодный старт), чем если бы оно уже было открыто один раз (теплый старт).

Большая часть (если не все) различий, по-видимому, связана с загрузкой DLL: когда DLL находятся в страницах кэшированной памяти, они загружаются намного быстрее.Мы попробовали использовать ClearMem для имитации перезагрузки (поскольку это занимает гораздо меньше времени, чем фактическая перезагрузка) и получил неоднозначные результаты: на некоторых машинах казалось, что перезагрузка имитируется очень последовательно, а на некоторых нет.

Подводя итог, мои вопросы:

  1. Замечали ли вы разницу во времени запуска при холодном и теплом запуске?
  2. Как вы справились с такими различиями?
  3. Знаете ли вы способ надежно имитировать перезагрузку?

Редактировать:

Пояснения к комментариям:

  • Приложение в основном представляет собой собственный C++ с некоторым количеством .NET (первая загруженная сборка .NET оплачивает CLR).
  • Мы стремимся сократить время загрузки. Очевидно, мы выполнили свою часть профилирования и улучшили активные точки в нашем коде.

Я забыл упомянуть, что мы добились некоторого улучшения, перебазировав все наши двоичные файлы, чтобы загрузчику не приходилось делать это во время загрузки.

Это было полезно?

Решение

Как вы профилировали свой код?Не все методы профилирования одинаковы, и некоторые находят «горячие точки» лучше, чем другие.Вы загружаете много файлов?В этом случае могут сыграть роль фрагментация диска и время поиска.

Возможно, даже добавление базовой информации о времени в код, запись в файл журнала и проверка файлов при холодном/теплом запуске помогут выявить где приложение тратит время.

Без дополнительной информации я бы склонился к файловой системе/кэшу диска как к вероятной разнице между двумя средами.В этом случае вам нужно либо тратить меньше времени на предварительную загрузку файлов, либо найти более быстрые способы загрузки файлов.

Пример:Если вы загружаете множество файлов двоичных данных, ускорьте загрузку, объединив их в один файл, а затем выполните сканирование всего файла в памяти за одно чтение и проанализируйте его содержимое.Меньше операций поиска по диску и затрат времени на чтение с диска.Опять же, возможно, это не применимо.

Я не знаю каких-либо инструментов для очистки кэша диска/файловой системы, но вы можете написать быстрое приложение, которое считывает с диска кучу несвязанных файлов, чтобы вызвать загрузку кэша файловой системы/диска различной информацией.

Другие советы

Что касается моделирования перезагрузок, рассматривали ли вы возможность запуска приложения из виртуальный ПК?Используя виртуализацию, вы можете удобно повторять набор условий снова и снова.

Я бы также рассмотрел какой-нибудь тип приложение для профилирования определить фрагмент кода, вызывающий задержку во времени, а затем принять решение о том, какая часть этого кода действительно необходима или можно ли этого достичь другим способом.

Было бы сложно смоделировать перезагрузку программно.При перезагрузке на всех устройствах вашего компьютера устанавливается бит сброса, что должно привести к потере всей общесистемной памяти.

В современной машине память и кэш есть повсюду:есть подсистема виртуальной машины, которая хранит страницы памяти для программы, есть операционная система, кэширующая содержимое файлов в памяти, а также есть дисковый буфер секторов на самом жестком диске.Возможно, вам удастся сбросить кеши ОС, но дисковый буфер на диске?Я не знаю способа.

@Мортен Кристиансен сказал:

Один из способов ускорить холодный запуск приложений (вроде как) используется, например.Adobe Reader, загружая часть файлов при запуске, тем самым скрывая от пользователей холодный запуск.Это можно использовать только в том случае, если программа не должна запускаться немедленно.

Это заставляет клиента платить за инициализацию нашего приложения при каждой загрузке, даже если оно не используется. Мне этот вариант действительно не нравится (как и Раймонд).

Одним из успешных способов ускорить запуск приложений является переключение DLL на отложенную загрузку.Это недорогое изменение (некоторые изменения в настройках проекта), но оно может значительно ускорить запуск.После этого запустите файл depend.exe в режиме профилирования, чтобы выяснить, какие библиотеки DLL все равно загружаются во время запуска, и отмените для них задержку загрузки.Помните, что вы также можете отложить загрузку большинства необходимых вам библиотек Windows DLL.

Очень эффективный метод сокращения времени холодного запуска приложения — оптимизация порядка ссылок на функции.

Компоновщик Visual Studio позволяет передать в файл список всех функций связываемого модуля (или только некоторых из них — это не обязательно все), и компоновщик разместит эти функции рядом друг с другом в Память.

Когда ваше приложение запускается, обычно во всем приложении выполняются вызовы функций инициализации.Многие из этих вызовов будут адресованы страницам, которых еще нет в памяти, что приведет к ошибке страницы и поиску на диске.Отсюда и медленный запуск.

Оптимизация вашего приложения для объединения всех этих функций может стать большой победой.

Ознакомьтесь с оптимизацией на основе профиля в Visual Studio 2005 или более поздней версии.Одна из вещей, которую PGO делает для вас, — это упорядочивание ссылок на функции.

Работать над процессом сборки немного сложно, потому что с помощью PGO вам нужно связать, запустить приложение, а затем повторно связать его с результатами запуска профиля.Это означает, что ваш процесс сборки должен иметь среду выполнения и выполнять очистку после плохих сборок и все такое, но выигрыш обычно составляет более чем в 10 раз более быстрый холодный запуск без изменений кода.

Еще немного информации о PGO здесь:

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

В качестве альтернативы списку порядка функций просто сгруппируйте код, который будет вызываться, в одних и тех же разделах:

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

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

Его должно быть легко поддерживать при изменении кода, но он имеет те же преимущества, что и список порядка функций.

Я не уверен, может ли список порядка функций также указывать глобальные переменные, но использование этого #pragma data_seg просто сработает.

Один из способов ускорить холодный запуск приложений (вроде как) используется, например.Adobe Reader, загружая часть файлов при запуске, тем самым скрывая от пользователей холодный запуск.Это можно использовать только в том случае, если программа не должна запускаться немедленно.

Еще одно замечание: .NET 3.5SP1 предположительно имеет значительно улучшенную скорость холодного запуска, хотя я не могу сказать насколько.

Это могут быть NIC (карты LAN), и что ваше приложение зависит от некоторых других услуг, которые требуют от сети.Таким образом, профилирование вашего приложения само по себе может не дать вам этого, но вам следует изучить зависимости вашего приложения.

Если ваше приложение не очень сложное, вы можете просто скопировать все исполняемые файлы в другой каталог, это должно быть похоже на перезагрузку.(Кажется, вырезать и вставить не работает, Windows достаточно умна, чтобы знать, что файлы, перемещаемые в другую папку, кэшируются в памяти)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top