Как я могу получить байты для чтения? - PullRequest
1 голос
/ 28 апреля 2010

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

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

РЕДАКТИРОВАТЬ: Документ по теме http://www.azulsystems.com/events/mspc_2008/2008_MSPC.pdf

Ответы [ 4 ]

5 голосов
/ 29 апреля 2010

Вы действительно можете использовать свой второй метод, по крайней мере, в Linux. mmap() файла, затем используйте функцию mincore(), чтобы определить, какие страницы являются резидентными. Со страницы руководства:

int mincore(void *addr, size_t length, unsigned char *vec);

mincore() возвращает вектор, который указывает, являются ли страницы вызова Виртуальная память процесса является резидентной в ядре (ОЗУ) и так не вызовет доступ к диску (ошибка страницы), если ссылки. Ядро возвращается информация о месте жительства страницы, начинающиеся с адреса addr, и продолжается length байт.

Конечно, здесь есть условие гонки - mincore() может сказать вам, что страница является резидентной, но она может быть заменена непосредственно перед тем, как вы получите к ней доступ. C'est la vie .

2 голосов
/ 28 апреля 2010

Вы исходите из неверного предположения. По крайней мере, в Linux ОС попытается выяснить шаблоны доступа к программе. Если вы читаете файл последовательно, ядро ​​будет выполнять предварительную выборку последовательно. Если вы будете часто перемещаться по файлу, ядро, вероятно, сначала будет сбит с толку, но затем прекратит предварительную выборку.

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

Попробуйте подойти к этому по-другому. Перед вызовом read (), чтобы получить информацию, которая вам нужна , позвоните fadvise () , чтобы ОС узнала, что вы хотите , чтобы начать загрузку ..

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

1 голос
/ 28 апреля 2010

Какой API можно использовать, чтобы узнать, что находится в кешах ОС?

Конечно, нет стандартного способа сделать это для любой системы posix, и я не знаю ни одного нестандартного способа, специфичного для Linux. Единственное, что вы можете знать (почти) наверняка, - это то, что файловая система будет считывать информацию, кратную размеру страницы, обычно 4 КБ. Таким образом, если ваши чтения невелики, вы можете с большой вероятностью (хотя и не наверняка) знать, что данные на соседней странице находятся в памяти.

Вы могли бы, я полагаю, делать хитрые вещи, такие как определение времени, сколько времени потребовалось для завершения системы чтения. Если это быстро, то есть 100 с или менее микросекунд, это, вероятно, было попаданием в кеш. Как только он достигнет миллисекунды или около того, это, вероятно, была ошибка кэша. Конечно, это на самом деле не очень вам помогает, и это очень и очень хрупко.

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

Наконец, я подхожу к @ предложению Кармастана: объясните более широкий конец, к которому вы стремитесь. Вероятно, есть способ сделать это, но тот, который вы предложили, не так ли.

1 голос
/ 28 апреля 2010

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

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

Если вы действительно хотели сделать что-то подобное в Windows, вы можете отключить буферизацию и управлять буферами самостоятельно. Это самый быстрый путь ввода-вывода, но он также и самый сложный - вы должны быть очень осторожны, и зачастую ОС может делать это лучше.

...