Чтение файла по сети медленное из-за дополнительных чтений - PullRequest
6 голосов
/ 10 января 2010

Я читаю файл и читаю либо строку данных (1600 последовательных чтений по 17 байтов), либо столбец данных (1600 чтений из 17 байтов, разделенных 1600 * 17 = 27 200 байтов). Файл находится на локальном или удаленном диске. Я выполняю чтение 10 раз, поэтому в каждом случае ожидаю прочтения 272 000 байт данных.

На локальном диске я вижу то, что ожидаю. На удаленном диске при последовательном чтении я также вижу то, что ожидаю, но при чтении столбца я вижу тонну дополнительных операций чтения. Они имеют длину 32 768 байт и, похоже, не используются, но они позволяют увеличить объем считываемых данных с 272 000 байт до 79–106 МБ. Вот вывод с использованием Process Monitor:

1:39:39.4624488 PM  DiskSpeedTest.exe   89628   ReadFile    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,390,069, Length: 17
1:39:39.4624639 PM  DiskSpeedTest.exe   89628   FASTIO_CHECK_IF_POSSIBLE    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Operation: Read, Offset: 9,390,069, Length: 17
1:39:39.4624838 PM  DiskSpeedTest.exe   89628   ReadFile    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,388,032, Length: 32,768, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal
1:39:39.4633839 PM  DiskSpeedTest.exe   89628   ReadFile    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,417,269, Length: 17
1:39:39.4634002 PM  DiskSpeedTest.exe   89628   FASTIO_CHECK_IF_POSSIBLE    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Operation: Read, Offset: 9,417,269, Length: 17
1:39:39.4634178 PM  DiskSpeedTest.exe   89628   ReadFile    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,444,469, Length: 17
1:39:39.4634324 PM  DiskSpeedTest.exe   89628   FASTIO_CHECK_IF_POSSIBLE    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Operation: Read, Offset: 9,444,469, Length: 17
1:39:39.4634529 PM  DiskSpeedTest.exe   89628   ReadFile    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,441,280, Length: 32,768, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal
1:39:39.4642199 PM  DiskSpeedTest.exe   89628   ReadFile    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,471,669, Length: 17
1:39:39.4642396 PM  DiskSpeedTest.exe   89628   FASTIO_CHECK_IF_POSSIBLE    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Operation: Read, Offset: 9,471,669, Length: 17
1:39:39.4642582 PM  DiskSpeedTest.exe   89628   ReadFile    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,498,869, Length: 17
1:39:39.4642764 PM  DiskSpeedTest.exe   89628   FASTIO_CHECK_IF_POSSIBLE    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Operation: Read, Offset: 9,498,869, Length: 17
1:39:39.4642922 PM  DiskSpeedTest.exe   89628   ReadFile    \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,498,624, Length: 32,768, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal

Обратите внимание на дополнительные считывания 32 768 с флагами ввода / вывода, установленными на некэшированные, ввод / вывод на пейджинге, синхронный ввод / вывод на пейджинг, приоритет: нормальный. Это дополнительные операции чтения, которые берут его с 272 КБ до 106 МБ и вызывают медлительность. Они не происходят при чтении из локального файла или при чтении строки, поэтому все последовательно.

Я попытался установить FILE_FLAG_RANDOM_ACCESS, но, похоже, это не помогло. Любые идеи о том, что вызывает эти дополнительные чтения и как их остановить ???

Тесты выполняются в 64-битной системе Vista. Я могу предоставить исходный код для программы, чтобы продемонстрировать проблему, а также консольную программу, которая выполняет тесты.

Ответы [ 5 ]

2 голосов
/ 29 ноября 2011

Я нашел ответ на это. Windows выполняет чтение файлов через кеш страниц, поэтому, когда я читаю 17 байт, сначала нужно перенести полную страницу размером 32 КБ, а затем скопировать нужные 17 байт из кеша страниц. Неприятный результат по производительности!

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

Таким образом, операционная система делает много вещей за сценой, что затрудняет проведение хорошего тестирования производительности!

2 голосов
/ 13 января 2010

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

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

Вы прочтете несколько ночных кошмаров об оплоках и базах данных простых файлов.

http://msdn.microsoft.com/en-us/library/aa365433%28VS.85%29.aspx

Не уверен, решит ли это вашу проблему, но может привести вас в правильном направлении. Удачи!

0 голосов
/ 17 января 2010

Я думаю, что SMB всегда передает блок, а не небольшой набор байтов.

Некоторую информацию о согласовании размера блока можно найти здесь. http://support.microsoft.com/kb/q223140

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

Исправление, очевидно, зависит от контроля над приложением, а также от размера и структуры базы данных. (Например, если база данных имеет один столбец на файл, то все чтения будут последовательными. Если вы используете сервер базы данных, вы не будете использовать SMB и т.

Если это утешит, iTunes работает ужасно при использовании сетевого диска тоже .

0 голосов
/ 16 января 2010

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

Извлечение раздела кэширования раздела API CreateFile.

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

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

0 голосов
/ 15 января 2010

Я вижу это все время, и это вне вашего контроля: сеть делает то, что хочет.

Если вы знаете, что размер файла будет меньше 1 МБ, просто поместите все это в память.

...