У меня есть программа, которая загружает файл (от 10 МБ до 5 ГБ) порцию за раз (ReadFile), и для каждого порции выполняет набор математических операций (в основном вычисляет хэш).
После вычисления хеша он сохраняет информацию о чанке в карте STL (в основном <chunkID, hash>
), а затем записывает сам чанк в другой файл (WriteFile).
Вот и все, что он делает. Эта программа приведет к тому, что некоторые компьютеры задохнутся и умрут. Мышь начинает заикаться, диспетчер задач показывает> 2 минуты, ctrl + alt + del не отвечает, запущенные программы работают медленно ... работает.
Я сделал буквально все, что мог придумать, чтобы оптимизировать программу, и трижды проверил все объекты.
Что я сделал:
- Пробовал разные (менее интенсивные) алгоритмы хеширования.
- Переключил все распределения на nedmalloc вместо нового оператора по умолчанию
- Переключившись с stl :: map на unordered_set, я обнаружил, что производительность по-прежнему ужасна, поэтому я снова переключился на Google D плотности_hash_map.
- Преобразовал все объекты для хранения указателей на объекты вместо самих объектов.
- Кэширование всех операций чтения и записи. Вместо того, чтобы читать 16-килобайтный фрагмент файла и выполнять математические операции с ним, я считал 4 МБ в буфер и вместо этого прочитал 16-килобайтный фрагмент из там . То же самое для всех операций записи - они объединяются в блоки по 4 МБ перед записью на диск.
- Запуск расширенного профилирования с помощью Visual Studio 2010, AMD Code Analyst и perfmon.
- Установить приоритет потока как THREAD_MODE_BACKGROUND_BEGIN
- Установить приоритет потока как THREAD_PRIORITY_IDLE
- Добавлен вызов Sleep (100) после каждого цикла.
Даже после всего этого приложение по-прежнему приводит к зависанию всей системы на определенных машинах при определенных обстоятельствах.
Perfmon и Process Explorer показывают минимальную загрузку ЦП (в режиме ожидания), отсутствие постоянных операций чтения / записи с диска, мало жестких сбоев страниц (и всего ~ 30 Кбайт страниц при жизни приложения во входном файле 5 ГБ), мало виртуальной памяти (никогда не превышает 150 МБ), никаких утечек, утечек памяти.
Машины, которые я тестировал на Windows XP - включая версии Windows 7, x86 и x64. Ни один из них не имеет менее 2 ГБ ОЗУ, хотя проблема всегда усугубляется при более низких условиях памяти.
Я не знаю, что делать дальше. Я не знаю, что вызывает это - я разрываюсь между процессором или памятью, как виновник. Процессор, потому что без сна и при разных приоритетах потоков производительность системы заметно меняется. Память, потому что существует огромная разница в том, как часто проблема возникает при использовании unordered_set и Google's dens_hash_map.
Что на самом деле странного? Очевидно, что дизайн ядра NT должен предотвращать подобное поведение когда-либо (приложение пользовательского режима, приводящее систему к такой крайне низкой производительности! скомпилируйте код и запустите его на OS X или Linux (это достаточно стандартный C ++ для всех), он отлично работает даже на слабых машинах с небольшим объемом оперативной памяти и более слабыми процессорами.
Что я должен делать дальше? Откуда мне знать, что, черт возьми, Windows делает за кулисами, что убивает производительность системы, когда все признаки того, что само приложение не делает ничего экстремального?
Любой совет будет приветствоваться.