Резкое повышение производительности в .NET CF после того, как приложение вышло на передний план. Зачем? - PullRequest
1 голос
/ 09 марта 2012

У меня есть большая (500 тыс. Строк) программа .NET CF (C #), работающая на CE6 / .NET CF 3.5 (v.3.5.10181.0).Это работает на FreeScale i.Mx31 (ARM) @ 400MHz.Он имеет 128 МБ ОЗУ, ~ 80 МБ доступно для приложений.Мое приложение является единственным значимым (это выделенная встроенная система).Используемая управляемая память (как сообщает GC.Collect) составляет около 18 МБ.Чтобы лучше понять размер приложения, вот некоторые статистические данные, полученные из .NET CF Remote Performance Monitor после запуска приложения:

GC:
 Garbage Collections            131 
 Bytes Collected by GC          97,919,260
 Managed Bytes in use after GC  17,774,992
 Total Bytes in use after GC    24,117,424
 GC Compactions                 41
JIT:
 Native Bytes Jitted:           10,274,820
Loader:
 Classes Loaded                 7,393
 Methods Loaded                 27,691

Недавно я пытался отследить проблему с производительностью.Я обнаружил, что мой тест после запуска приложения в двух разных конфигурациях запуска будет работать примерно за 2 секунды (медленный случай) против 1 секунды (быстрый случай).В медленном случае время для эталонного теста может меняться случайным образом с запуска EXE до запуска EXE с 1,1 до 2 секунд, но для любого данного запуска EXE не изменится в течение срока службы приложения.Другими словами, вы можете перезапустить тест, и время теста останется прежним, пока вы не перезапустите EXE, после чего будет установлено и согласовано новое время.

Я не мог объяснить замедление от 1.1 до 2x с помощью какого-либо традиционного механизма или сужения замедления до какой-либо конкретной части кода теста.Оказалось, что весь процесс просто работал медленнее, почти как поток вращался и отбирал часть моего «процессора».

Затем я случайно обнаружил, что просто переключаясь с моего приложения (графический интерфейс проигрываетна переднем плане) в другое приложение, моя проблема производительности исчезает.Он остается даже после возвращения моего приложения на передний план.Теперь у меня есть пробный обходной путь, когда мое приложение после запуска запускает вспомогательное приложение с окном размером 1x1, которое самоубийственно после 5 мс.Таким образом, приложение aux выходит на передний план, а затем отказывается от него.

Вопрос в том, почему это ускоряет мое приложение?

Я знаю, что код передается, когда приложение .NET CF теряет приложение.на переднем плане.Я также заметил, что при выполнении захвата «кучи GC» с помощью .NET CF Remote Performance Monitor регистрируется шаг кода - и это также приводит к повышению производительности в моем приложении.Так что я подозреваю, что качка кода связана или даже ответственна за исправление производительности.Но я не могу понять, как определить, так ли это на самом деле, или даже объяснить, почему передача кода может помочь в этом.Достаточно ли существенно помогает выделение большого количества кода для локальности ссылок на кодовые страницы (которые повторно JITted, предположительно, расположены рядом друг с другом в памяти), чтобы помочь в этом?(Мой бенчмарк охватывает, вероятно, 3 десятка подпрограмм и сотни строк кода.)

Самое главное, что я могу сделать в своем приложении, чтобы надежно избежать этого более медленного состояния.Будем весьма благодарны за любые ссылки на соответствующую информацию о .NET CF / JIT / Code.

Ответы [ 3 ]

1 голос
/ 22 марта 2012

Отправьте ваше приложение wm_hibernate до цикла производительности.Уберут вещи

1 голос
/ 10 марта 2012

Ваше приложение, отправляющееся в фоновый режим, автоматически запускает сбор GC.Collect, который может сжать кучу GC и может передать код.Вы проверили, дает ли руководство GC.Collect без перехода в фоновый режим такое же поведение?Это может быть не качка, которая дает прирост производительности, это может быть сбор или уплотнение.Если значительное количество мертвых корней выметено, прогулка по корневому дереву может стать быстрее.Не могу сказать, что я специально видел эту проблему, так что это все догадка.

0 голосов
/ 23 апреля 2015

У нас похожая проблема с нашим приложением .NET CF.

Со временем наше приложение постепенно замедляется, в конечном итоге останавливается, что, как я ожидаю, связано с высокой загрузкой ЦП или, как говорит @ wil-s, как будто поток вращается, потребляя ЦП. Единственное предположение /, которое я сделал к настоящему моменту, заключается либо в том, что в нашем коде есть мошенническая нить, либо в .NET CF есть проблема под прикрытием, возможно, с JITter.

Закрытие приложения и его повторный запуск возвращает наше приложение к нормальной ожидаемой производительности.

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

Однако впоследствии мне будет интересно узнать, была ли когда-либо найдена основная причина этой конкретной проблемы?

Между прочим и, казалось бы, не по теме (но потерпите меня) мы используем процессор Freescale i.MX28 и испытываем непредсказуемое повреждение FlashDisk. Просмотр 2K блоков 0xFF (стертых блоков) в случайных файлах, расположенных на NAND Flash.

Я упоминаю об этом, поскольку теперь я считаю, что проблемы с повреждением процессора и FlashDisk связаны между собой этой статьей и этой статьей: https://electronics.stackexchange.com/questions/26720/flash-memory-corruption-due-to-electricals

В статье @ jwygralak67 комментирует:

Недавно я работал над проблемой повреждения флэш-памяти в системе WinCE, как часть команды разработчиков. Мы бы случайно нашли 2K блоков вспышка, которые были стерты. (Все байты 0xFF) В течение 6 месяцев мы тестировали все от электростатического разряда, грязного питания до помех и радиопомех, мы купил новые устройства и отслеживал использование, чтобы убедиться, что мы не были превышение предела цикла стирания и вырубки блоков, мы прошли наше (прикладное) программное обеспечение с тонкой зубчатой ​​гребенкой.

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

К сожалению, мы еще не связались с ним.

Имея все это в виду, потенциально , если мы справимся с высокой загрузкой ЦП, , может быть , повреждения больше не будет. Еще один случай предположения! Однако, исходя из этого предположения, это не дает твердой причины для любой ситуации, которую я отчаянно ищу!

Любое знание или понимание, пусть даже маленькое, будет с благодарностью получено.

@ ctacke - мы уже говорили об OpenNETCF по электронной почте, поэтому я рад видеть ваше имя!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...