iGrok писал(а):Хакер писал(а):если человек пишет на чём-то высокоуровневом
Ну, это да. Но, скажем, браузеры-то пока ещё пишут на плюсах. Да и множество другого софта тоже. А проблемы там ровно те же.
Дело в том, что «плюсы» — это уже «что-то высокоуровневое».
Потому что программисты используют Boost, Qt и т.п. вещи. И в коде, опять же, не оказывается места для VirtualLock.
Вот например Google Chrome. Не раз видел в его рекламе слоган «Быстрый». Посмотрим:
- google_chrom_kernel_imports_near_virtual.png (23.11 Кб) Просмотров: 6040
— VirtualLock? — Не, не слышал!Хотя написан на С++ и, говорят, частично даже на ассемблере.
FireFenix писал(а):Если я правильно помню, VirtualLock не даёт выгрузить в своп.
А теперь вопрос, нафига держать программы в фоне с большим потреблением ОЗУ?
FireFenix, меня бесят до состояния осатанения люди, которые говорят мне, что я неправильно пользуюсь системой и софтом, и что это я должен подстраиваться под криво написанный софт и не запускать больше двух программ одновременно, а не тупые наивные разработчики должны подстраиваться под моё желание запускать 300 процессов одновременно.
Это всё равно, что купить Феррари, а на следующий день она сломается, и в сервисе тебе скажут «а, ну что же вы, дорогой, хотите, ведь вы ездили на ней со скоростью больше 100 км/ч; вот если бы ездили со скоростью 40 км/ч — она бы вам 15 лет без проблем прослужила». Это надувательство. Спасибо, но у нас уже были времена DOS с однозадачностью. Теперь у нас времена многозадачности. Теперь у меня есть процессор с 8 ядрами, чтобы в 8 раз быстрее обрабатывать сотни конкурирующих потоков.
И, слава богу, процессора мне хватает всегда — он всегда холодный, как бы я не загрузил систему, а вот чего мне действительно не хватает, так это пропускной способности интерфейса
память—диск. Потому что
хр-хр, которое доносится во время очередных тормозов, говорит о том, что где-то там возникла пробка, транспортный коллапс. И оно говорит о том, что общая картина такова, что системе приходится гонять терабайты данных туда и обратно.
И я не верю, что есть какая-то реальная потребность гонять терабайты данных туда-сюда, а дело скорее в неэффективном использовании ресурсов.
Google Chrome быстр только тогда, когда он — единственный прикладной процесс.
Горькая правда в том, что все эти горе-программисты и проектируют, и пишут, и тестируют свой жалкий софт с убеждённостью, что их программа будет единственной, которая будет работать на компьютере.
Тогда им действительно не нужен VirtualLock. Тогда их программа действительна быстра, как дьявол.
Кстати ещё один момент тупости: как проимплементирована реакция на WM_SIZE. Проблема в том, что WM_SIZE как правило запускает целый каскад перемасштабирования дочерних окон/контролов, у некоторых из которых тоже есть какие-то дочерние элементы. Всё это требует кучи пересчётов и перемещений элементов. Как программист проверяет, что всё это реализовано хорошо? Он просто пробует ресайзить окно мышкой. И оно ресайзится очень быстро без каких-либо лагов. Вывод — оптимизация не нужна, зачем тратить время. К тому же, наверняка, ресайз главного окна вызывает ресайз контролов, а контролы чужие и код ресайза в них вообще не переделать. Но ведь всё работает быстро. Прекрасно. Теперь, когда открыто 100 окон, попробуйте ресайзнуть панель задач (или скрыть/показать приложение, прилепляющееся к границе экрана). Эти сто окон помимо WM_SETTINGCHANGE (из-за изменения workarea) получат ещё и WM_SIZE. После этого можно отойти от компьютера, налить себе кофе, выпить его, потому что всё намертво зависнет на пару минут. Ибо время, за которое сто окон обработают одновременно пришедшее WM_SIZE, не равно сумме времён, за которые каждое окно из сотни обработает это сообщение. А на порядок или два — больше этой суммы. Поэтому реакцию на WM_SIZE нужно жестко оптимизировать. Но никто не делает.Если Google Chrome был свёрнут 4 часа назад и с тех пор не разворачивался, но зато с тех пор запускался фотошоп, несколько виртуальных машин, делался рендер видео в Vegas-е, и теперь вдруг мне захотелось развернуть Chrome — то он развернётся не мгновенно, а через секунды 3—4.
Но если ренден видео в Вегасе идёт прямо сейчас, то он развернётся через 40 секунд.
Или вот типичный сценарий: браузер давно лежат свёрнутым, а тут я его развернул и читал текст из вкладки. Прочитал. Слава гуглу! Теперь я кликаю на корешок вкладки, которая вообще пустая. В этой вкладки не открытка никакая страница.
Хром виснет на 6 секунд. Харды делают протяжное хррр-р-р-ррр-рр.
Последующие переключения между вкладками быстры как никогда. Но певая попытка перейти на пустую вкладку заняла 6 секунд.
Потому что в из working set-а были исключены страницы, которые оказались нужны, чтобы обработать переключение.
Это может быть 5 страниц, но они могут лежать в разных местах виртуального АП, и это будет 5 отдельных page-fault-ов, и это будет 5 отдельных page-in-ов, то есть 5 чтений с диска, и это могут быть разные места файла подкачки, и с учётом того, что Chrome — не единственный процесс, которому нужно что-то читать с диска, это и занимает те 6 секунд.
Так вот, такие вещи, как таблица дескрипторов браузерных вкладок — должны быть локнуты. Это значит, что пустая вкладка откроется мгновенно, а вкладка с огромным документом откроется за 3 секунды. Я недоволен, но меня устраивает ситуация, когда пустая вкладка откроется мгновенная, в вкладка с большим документом — за 3 секунды, и когда время открытия вкладки будет пропорционально размеру документа. Но меня абсолютно не устраивает, когда даже открытие пустой вкладки вешает процесс на 6 секунд.
Маленькие массивы дескрипторов, хеш-таблицы, кеши — любые структуры, доступ к котором может потребоваться в произвольный момент времени, и должен произойти быстро, должно быть локнуты.
Другая вещь, для которой VirtualLock ещё более важен — это пробежки по большим цепочкам данных.
Если нужно пробежаться по большому массиву — то значит нужно его локать. Полностью или по частям (в зависимости от размера массива). Если нужно не только пробежаться, но и каждый элемент массива требует обращения к некоторой другой структуре, значит нужно заранее локнуть эту структуру, а потом локать фрагменты большого массива.
Потому что представьте, что пробежка по большой цепочке страниц происходит регулярно. Если цепочка такова, что все страницы не умещаются в WS, то значит
в данный момент скорее всего начало цепочки отсутствует в WS, а конец цепочки — присутствует, потому что обращение к нему было последним.
И вот вам надо опять пробежаться по цепочке страниц. Обращение к первой же страницы из цепочки приводит к page-fault-у. Чтобы загрузить в физическую память первую страницу цепочки, система выкинет в своп конец цепочки.
Подвох понятен?
У менеджера памяти нет искусственного интеллекта. Менеджер памяти понятия не имеет о цепочки. Для него страницы, входящие в цепочку, ничем не лучше какой-нибудь мусорной страницы.
В рабочем наборе уже есть конец цепочки, но чтобы загрузить туда начало, конец будет выкинут. И совсем скоро понадобится обратиться уже к концу, и придётся
загрузить только что выгруженный конец, выкинув начало.
Вот это и есть тот самый сценарий, когда данные бесполезно и неэффективно гоняются туда-сюда.У системы нет дара предвидения, чтобы предугадать, что за обращением к странице X обязательно последует обращение к странице Y. Система не знает, что ради X будет глупо выгружать Y, потому что следом понадобится загрузить Y. Но программист знает. И код знает, что он делает и куда пойдёт обращение.
Поэтому:
Дайте системе подсказку.Конечно, менеджер памяти написан по умному. И он пытается предсказывать, к каким страницам обращения будут чаще, чем к остальным. И он неплохо справляется. Но не всегда. Иногда он может предсказывать неправильно. Он угадывает, а у программиста есть возможность дать ему знать навеняка. Но программисты слишком ленивы, наивны и тупы, чтобы воспользоваться этим шансом избежать лишнего копирования данных туда-сюда.