Пользовательская предварительная выборка

Любые программные методы, переносимые или специфичные для NT и Linux, которые позволяют быстрее загружать большие файлы? Мне нужен «заблаговременно», заранее, как бы вы это ни называли, механизмы, которыми я могу управлять в коде для двух ОС в вопросе.

Каждый файл должен быть обработан полностью, т.е. полностью по размеру и последовательно по его содержимому. Цель состоит в том, чтобы ускорить обработку некоторых пакетных файлов.


person rama-jka toti    schedule 13.10.2009    source источник


Ответы (2)


Я не знаю API Win32 (NT), похожего на madvise().

Тем не менее, я бы предложил подход.

Сначала передайте флаг Win32 FILE_FLAG_SEQUENTIAL_SCAN в CreateFile(). Это позволит операционной системе Windows выполнять лучшую буферизацию файла после его открытия.

С FILE_FLAG_SEQUENTIAL_SCAN ваш анализатор файлов может работать быстрее, когда файл находится в памяти. В отличие от madvise() в Linux, файл не начнет загружаться в память раньше из-за использования флага Win32.

Затем нам нужно запустить файл, чтобы начать загрузку. Асинхронно прочитайте первую страницу файла, вызвав ReadFileEx() со структурой OVERLAPPED и функцией FileIOCompletionRoutine.

Ваш FileIOCompletionRoutine может просто вернуться, или вы можете установить событие в перекрывающейся структуре — читайте подробности MSDN о ReadFileEx для деталей.

Поскольку это не будет критическим сбоем, если предварительная выборка не будет завершена, когда вы фактически читаете из файла, самой простой реализацией будет «запустить и забыть» — выполнить чтение перекрывающегося файла, а затем никогда не проверять результат Это. Однако убедитесь, что вы читаете данные в действительные буферы!

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

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

Предложение bdonlan о потоке «предварительной выборки», который асинхронно загружает файлы из обработки, также было бы рабочим решением для Win32.

person Heath Hunnicutt    schedule 13.10.2009
comment
приветствую оба ваших комментария. Я знаю о file_flag_sequential и предлагаемых методах, но мне было интересно, есть ли какой-либо явный контроль над тем, что осталось: ОС XP + для предварительной выборки, поэтому реклама, скажем, в SuperFetch и других формах :) Вид стыдно, если нет способа сделать это, так как это, очевидно, работает в NT, даже более очевидно, чем в Linux, я бы сказал. С другой стороны, я мог что-то упустить, когда искал явный контроль, но безрезультатно ... пусть вопрос будет запущен в течение дня, прежде чем принять ответ или другие предложения. Спасибо.. - person rama-jka toti; 14.10.2009
comment
Я считаю, что SuperFetch — это лишь немного больше, чем поток «предварительной выборки», хотя в этом случае: это целый процесс, а не поток, каким-то образом он получает информацию от ОС, что позволяет ему принимать решения о том, какие EXE и DLL файлы для переноса в память. - person Heath Hunnicutt; 14.10.2009
comment
Поспав на этом, я расширил свой ответ относительно Win NT. - person Heath Hunnicutt; 15.10.2009
comment
Поскольку у bdonlan было два плюса :), я приму ваше, хотя технически вы оба ответили на него. Я бы только добавил, что я бы уклонился от конкретных механизмов ОС через asio и получил бы лучшее из обоих миров. Тем не менее жаль, что нет явных механизмов, где вы можете и хотите контролировать большую часть предварительной выборки ОС. - person rama-jka toti; 15.10.2009

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

В качестве альтернативы, более переносимым вариантом было бы простое ручное опережающее чтение в отдельном потоке от вашего потока обработки буфера, то есть чтение данных для заполнения буфера X МБ в потоке A, обработка их так быстро, как вы можете, в потоке B .

person bdonlan    schedule 13.10.2009
comment
да .. и этот более портативный вариант в некотором роде заставит ОС (к разумному потреблению) использовать существующий механизм буферизации или предварительной выборки. Я уже использую его каким-то образом, но не через потоки, поскольку процедура охватывает время жизни процесса. Таким образом, интерес к намекам на ОС, особенно для большого оборота файлов. Спасибо и голосую за оба ответа .. - person rama-jka toti; 14.10.2009
comment
Вы по-прежнему можете использовать опцию readahead-thread — поместить ее в отдельный процесс, охватывающий время жизни других процессов, и передавать данные через общую память. Это сложнее, конечно, но вполне выполнимо. - person bdonlan; 15.10.2009