Windows 7: плохой отклик графического интерфейса в моей программе при загрузке данных; Есть ли способ улучшить это? - PullRequest
1 голос
/ 22 октября 2011

Я написал программу, которая (помимо прочего) загружает несколько больших файлов с сервера в локальной сети, используя TCP. Эта программа прекрасно работает в Linux, MacOS / X и, в целом, также в Windows (она использует Qt для графического интерфейса пользователя и прямых вызовов сокетов для работы в сети), но на некоторых компьютерах с Windows загрузка кажется слишком сложной для этой машины, и мне интересно, есть ли у кого-нибудь идеи о том, почему это так и что с этим можно сделать.

При загрузке файлов моя программа порождает отдельный поток ввода-вывода, который по сути просто сидит в цикле, загружая данные по TCP и записывая их в файл, записывая 128 КБ за вызов QFile: write (). Каждый файл обычно имеет длину несколько сотен мегабайт, и в типичном сеансе загрузки записывается несколько десятков этих файлов. Обратите внимание, что поток ввода-вывода работает независимо от потока графического интерфейса, поэтому я не ожидаю, что он сильно повлияет на производительность графического интерфейса, особенно если он работает на многоядерном ПК.

Данный компьютер представляет собой Core-2Duo Quad Q6600 с тактовой частотой 2,40 ГГц и 4 ГБ ОЗУ. Он работает под управлением Windows 7 Ultimate SP1, 32-разрядная версия. Он получает данные через соединение Gigabit Ethernet и записывает их в файлы в загрузочном разделе в формате NTFS на внутреннем диске Hitachi ATA емкостью 232 ГБ.

Симптом заключается в том, что иногда во время загрузки (казалось бы, наугад) графический интерфейс программы перестает отвечать на запросы в течение 10–30 секунд, и часто к строке заголовка окна добавляется «(не отвечает)» к этому. После этого симптом снова исчезнет, ​​и загрузка продолжится в обычном режиме. Другим симптомом является то, что рабочий стол очень вялый во время загрузки ... например, если я нажму на кнопку «Пуск», меню «Пуск» займет около 30 секунд, вместо того, чтобы заполняться почти мгновенно, как я и ожидал .

Обратите внимание, что диспетчер задач показывает много свободной памяти, но он показывает короткие скачки загрузки процессора до 100% одного из 4 ядер, в то же время проблемы видны.

Данные поступают через Gigabit Ethernet, и если моя программа просто получает данные и выбрасывает их (без записи на жесткий диск), машина может поддерживать постоянную скорость загрузки около 96 МБ / с без прерывания. пот. Однако если я записываю полученные данные в файл, скорость загрузки снижается примерно до 37 МБ / с, и начинают появляться симптомы, описанные выше.

Интересно то, что ради любопытства я добавил этот вызов в функцию ввода моего потока ввода-вывода перед самым началом его цикла событий:

SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);

Когда я это сделал, симптомы «(не отвечает)» исчезли, но затем скорость загрузки снизилась до всего ~ 25 МБ / с.

Итак, мои вопросы:

  • Кто-нибудь знает, что может вызывать спорадические зависания графического интерфейса, когда жесткий диск находится под большой нагрузкой записи?

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

  • Можно ли получить максимальную скорость загрузки, не вызывая проблем с отзывчивостью рабочего стола Windows и / или отзывчивостью моего приложения на графическом интерфейсе?

1 Ответ

0 голосов
/ 22 октября 2011

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

Кажется, он никогда не ждет и что драйвер сетевой карты плохо написан. Вы уверены, что ваш поток переходит в состояние ожидания, когда данные не поступают? В ОС с одним процессором a for (;;) {} будет потреблять 100% процессорного времени, и если он постоянно взаимодействует с ядром, он может остановить для этого другие процессы или другие потоки, особенно если есть ошибка или очень плохое поведение в каком-то драйвере сетевой карты в вашем случае.

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

Проверьте, не улучшит ли когда-нибудь добавление sleep (0), чтобы заставить операционную систему уступать другому потоку, но это временное исправление, вы должны выяснить, почему ваш поток потребляет 100% процессорного времени, если это так.

...